Unable to redirect from sharepoint event receiver - redirect

I have created an event receiver on the "Task" list.
If the "Due Date" is null then the user should be redirected to the custom error page.
Custom error page resides in the SharePoint mapped folder under "Layouts" directory.
The event receiver code is as follows:
public override void ItemAdding(SPItemEventProperties properties)
{
try
{
if (properties.AfterProperties["Due Date"] == null)
{
properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
properties.RedirectUrl = "_layouts/CustomErrorPage/DueDateErrorPage.aspx";
}
}
catch (Exception ex)
{
}
}
The custom error page which is of type "Application Page" having name. "DueDateErrorPage.aspx". The mark up is:
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
ERROR : You cannot create the task without due date
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Custom Error Page
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
Custom Error Page
</asp:Content>
Though in IIS, under the _layouts direcory the page is available I am getting this output.
How should I tackle this error? Please help.

I think your redirect url is invalid, because it will be relative to the current page, and not the current site or site collection.
You can diagnose this by looking at the dialog frame properties, and check the url.
Method 1 : solve the amgiguity
To resolve ambiguity, I suggest you to use the SPUtility.GetServerRelativeUrlFromPrefixedUrl method.
This will create a correct url.
Especially, change your code like this:
properties.RedirectUrl = SPUtility.GetServerRelativeUrlFromPrefixedUrl(
"~site/_layouts/CustomErrorPage/DueDateErrorPage.aspx"
);
This will dynamically resolve ~site to your current SPWeb url. You can also use ~sitecollection to resolve the site collection.
Method 2: make the field mandatory
Why don't you simply make the due date mandatory?
Method 3: use the standard sharepoint error page (not tested I admit)
Instead of redirecting to your own page, "Cancel" the event with a custom error message:
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage= "Due date is mandatory";
Moreover, CancelWithRedirectUrl is now obsolete.
PS: as a side note, you should know that a SharePoint dedicated Stack Exchange site exists.

First of all I first checked the url in web browser that is:
/_layouts/CustomErrorPage/DueDateErrorPage.aspx
It was opening the page that means the page is available but there is something missing in the url only.
So by using the SPUrlUtility class I was able to redirect the page.
The changes I needed to made was:
properties.RedirectUrl = SPUrlUtility.CombineUrl(properties.WebUrl,"/_layouts/CustomErrorPage/DueDateErrorPage.aspx");
It's working perfectly..

Related

Response redirect using IP in dotnetnuke

I am hosting and developer on my DNN portal. I need to redirect users using client IP. I think may be two ideas for this work.
1- DNN Setting
Maybe DNN has settings for it that I can set specific URL for client IP addresses and automatically DNN redirects to specific URL.
I read many topic but I could not find setting to do it.
Is there a way to do this?
2- New Module
I have a ascx that onload method has this code:
var IP = Server.HtmlEncode(Request.UserHostAddress).ToString();
using (Entities db = new Entities())
{
var retVal = db.URLAddresses.Where(u => u.IPAdress == IP).FirstOrDefault();
if (retVal != null)
Response.Redirect(retVal.URL);
}
But I should add this code to any ascx for redirect using client IP. This is impossible because maybe I haven't source code modules.
I think I should create new module. So I can add it to page. Module changes onload page and redirect to URL using client IP.
In this scenario, I try to create new module but I don't know how I can change onload method each page that is added module to it?
You can use IHttpModule and make a new Module for Including your class then you should add your IHttpModule to web.config .
For e.g
<add name="YourModule" type="YourAssembly, YourNameSpace" preCondition="managedHandler" />
See this Sites:
HTTP Handlers and HTTP Modules Overview
and How To Create an ASP.NET HTTP Module
DNN does have a Host setting that will allow or deny access to users logging in based on their IP address. It's in Host Settings > Advanced Settings > Login IP Filters. I don't think that will give you the desired result.
I would not suggest creating a module. It can be difficult copying it to all pages and ensuring one instance is added to every page.
Rather, I would create a skin (theme) token. To do this, create a simple class library project. Create an .ascx and ascx.cs file. You can leave the .ascx empty because you don't have any html to add to the pages. In the .cs, put something like this:
namespace MyCompany.DNN.Skin
{
public partial class IpRedirect : SkinObjectBase
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Put your redirect logic here
}
}
}
Then, in your theme/skin ascx pages, include the following:
<%# Register TagPrefix="myco" TagName="IPREDIRECT" Src="~/DesktopModules/MyCompany/IpRedirect/IpRedirect.ascx" %>
<myco:IPREDIRECT ID="pageRedirect" runat="server" />
This will ensure that this functionality will execute on all pages in the site that use the skin/theme.

Web2Py Redirect after login

I'm trying to redirect the user to another page (default/news) after the login(on default/index) but no matter how much i tried i couldn't get it done. I'm using the login available in the navbar.
I've added this line to db.py
auth.settings.login_next=URL(r=request, c='default', f='news')
Everything in the default controller is the same it includes
def news():
message = "Welcome to News!"
return locals()
I've also tried with this
auth.settings.login_next=URL('news')
Which doesn't work either. Please Help.
Edit:
After searching for days i've found the answer here This is how you do it.
#In layout.html change
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown") or ''}}</ul>
# to
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown",referrer_actions=None) or ''}}</ul>
And again a change in db.py
#In db.py add these lines:
auth.settings.login_next = URL('news')
That worked for me.
The auth.settings.login_next URL is only a default in case there is no referrer already in the login URL (the referrer is in the "_next" query string variable). The navbar automatically includes a referrer in the auth action links (set to the URL of the current page) -- to override that, you can explicitly specify thereferrer_actions argument and exclude actions for which the referrer should not be set:
{{=auth.navbar(..., referrer_actions=['register', ...])}}
It's now April 2016, and while the original question is still highly relevant, it appears that web2py has changed and the modifications suggested above to layout.html are no longer relevant. There is no reference to "auth.navbar" in the standard layout.html.
The good news is, that all one needs to do is include the python code described above in the default.py controller and it works. Note, I put it in the 'user' function, I'm not sure if that is the best place to put it as most comments just say to put it in 'the controller', without specifying a function.
def user():
auth.settings.login_next = URL('default','dashboard')
return dict(form=auth())
I was able to redirect to a user's home page after login/signup by putting the following code in my product info page.
This way, when they get redirected back to the welcome-product-info page, I check to see if they came from login or signup and direct them to where they should go.
I'd love to find way to use auth.settings.login_next
#
def info():
# If just signed up or just logged in, go to the user's home page and not
# back to this product landing page that referred them
if auth.is_logged_in():
if '/default/user/login?_next=/fnd/home/info' in request.env.http_referer:
redirect( URL( 'user', 'show_campaigns') )
if '/default/user/register?_next=/fnd/home/info' in request.env.http_referer:
redirect( URL( 'user', 'show_campaigns') )
return dict()

RestTemplate - Handle custom error message

I have Restful API that responds 404 errors when an item is not found, but have different messages depending on the reason why the item is not found (unknown, not available, ...), it is done this way using Spring MVC :
response.sendError(HttpServletResponse.SC_NOT_FOUND, "NOT_AVAILABLE");
(this works fine with any browser, displaying 404 errors with "NOT_AVAILABLE" as message)
Now, I'd like to get that message back into my Java code using Spring RestTemplate in order to manage them.
I tried this:
try {
rest.put(apiRootUrl + "/item/{itemId}", null, itemId);
} catch (HttpClientErrorException e) {
if (NOT_FOUND == e.getStatusCode()) {
switch (MyErrorCode.valueOf(e.getStatusText())) {
case NOT_AVAILABLE:
return displayNotAvailableError();
case UNKNOWN:
return displayUnknownError();
default:
// ...
}
}
}
but in the getStatusText(), I always got the NOT FOUND label (from 404) and not my custom value.
Does someone know if it is possible to retrieve the custom message from 404 errors? And therefore how?
thanks a lot!
Edit: I run on a Tomcat server (which sends the 404 HTML page) and this does not append with a Weblogic server
OK, after digging a bit more, the solution is in fact very simple !
Tomcat was sending back to me its default 404 page, I just needed to tell it to use mine!
How to do this:
create a 404.jsp page like this:
<%# page pageEncoding="UTF-8" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:out value="${requestScope['javax.servlet.error.message']}"/>
reference it in your web.xml
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
And now, you can get the message in your client using e.getStatusText()

TinyMCE 403 Forbidden page when using line breaks

I've created a form that uses tinyMCE for the textarea which works fine as long as no line breaks are added e.g. <br /> or <p> </p>.
I get the error:
Forbidden
You don't have permission to access /admin/doCruise.php on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Where, doCruise.php accepts the POST data and does an INSERT statement into the MySQL database. Permissions are fine as it works when no tags are there.
Any help would be greatly appreciated :)
Sorry for my English. But I am try to explain.
I think I fix it.
On your hosting mod_security block all content with html tags (on my too).
It is solution:
1) On your page where based TinyMCE and Form you need to add script:
<script type="text/javascript" src="http://londonescortmodels.co.uk/includes/jquery.base64.js"></script> //lib for base 64 encode
<script type="text/JavaScript">
$(document).ready(function(){
//------------------------//
// On submit //
//------------------------//
$("form").submit(function() { //Event on submit
tinyMCE.triggerSave(false, true); //Save content to textarea
$text=$("#elm1").val(); //get content from textarea
tinyMCE.activeEditor.setContent($.base64("encode",$text)); //encode content and return to TinyMCE
tinyMCE.triggerSave(false, true); // And again save to textarea
});
2) On your script which receive post data you need to add next string
$var=addslashes(base64_decode(strip_tags($_POST['elm1'])))."'"; //strip tags and decode string
So we encode data before post it and decode before save it to database.
Thank you for your time! Good luck.
I got the same error. It was a server issue. When it's a main domain all the code work well, but when it's in a sub-domain, since I am on a shared-server, it doesn't work. Hope it can help some one !

SiteFinity 4.0: Trouble Accessing Postback Data in Custom User Control

I'm trying to get a highly customized hand built form into sitefinity 4.0 and my problem is that no matter what I do I can't access the form's postback data in the code behind. My form is a user control and I've added it in the way described here:
http://www.sitefinity.com/40/help/developer-manual/controls-adding-a-new-control.html
After struggling for several hours, I created a basic test form and I'm still not able to access the postback data. I've also tried adding EnableViewState="true" all over the place but the form data is still empty on postback. The exact same user control runs and posts data perfectly outside of sitefinity. I also tried other methods of accessing the postback data and I discovered that Request.Form does contain the data I need. I'd still love to access my form elements in the usual way though, so I don't have to do Request.Form for every control on the page and loop that way, which seems really hokey.
Here's the code for the basic form:
"BasicUserControl.ascx"
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="BasicUserControl.ascx.cs" Inherits="SitefinityWebApp.UserControls.Assessments.BasicUserControl" EnableViewState="true" %>
<div id="assessmentDiv" runat="server">
<asp:TextBox ID="TextBox1" runat="server" clientidmode="Static" enableviewstate="true"></asp:TextBox>
<asp:Literal ID="Literal1" runat="server" clientidmode="Static" enableviewstate="true"></asp:Literal>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
"BasicUserControl.ascx.cs" Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SitefinityWebApp.UserControls.Assessments
{
public partial class BasicUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
Literal1.Text = TextBox1.Text;
}
}
}
}
Again, if I add the control via the method described at the link above, I am able to successfully create a Sitefinity 4.0 CMS page, drag the control onto it, run the page, step into the code behind using the debugger, yet when VS2010 reaches the line below there is no form data being posted:
Literal1.Text = TextBox1.Text;
FYI: The reason why there is no form tag in my usercontrol.ascx code above is because I get an error when running the form thru sitefinity that only one server-side form tag can exist on a .net page (sitefinity injects it's own form tag).
Thanks in advance for your help!
Ben
Never mind - I figured it out. For some reason, data isn't available at the Page_Load stage of the .net page lifecycle in a sitefinity form submission (at least not via a custom user control). If I wait until the Page_PreRender stage to retrieve the data from the form on the page, it's all there.
My current prevailing theory is that Sitefinity 4.0 grabs the postback data when a form submits and hasn't finished monkeying around with it at the Page_Load stage, so you have to wait until the Page_PreRender stage before sitefinity has injected the data back into the page cycle.
I had the same issue you did and came to the same solution. Spent a bunch of time on it - wish this answer had been around then.
Try adding enableviewstate into masterpages. I had the same situation and solved with this.
Also checked "enable view state" when creating pages.
Hope this help.
`<%# Master Language="C#" AutoEventWireup="true" CodeFile="HomePageClubManavgat.master.cs" Inherits="App_Master_HomePageClubManavgat" EnableViewState="true" %>
<script type="text/C#" runat="server">
protected override void OnInit(EventArgs e)
{
this.Page.EnableViewState = true;
base.OnInit(e);
}
`