It used to be a standard practice to use redirect in event receivers in SharePoint 2010 and SharePoint 2007. SharePoint 2013 has some changes in this functionality.
Redirect Option Availability
No redirect options available for ItemAdded, ItemUpdated and ItemDeleted.
Some redirect options available for ItemAdding, ItemUpdating and ItemDeleting. They are only available when the form, which initiates an event, is being rendered in CSRRenderMode.ServerRender mode. Otherwise list forms are committed through asynchronous XmlHttpRequests, and redirect options are not available.
CancelWithRedirectUrl - DOES NOT WORK
The following code does function:
properties.RedirectUrl = "http://www.google.com";
properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
Compiler is issuing the following warning:
'Microsoft.SharePoint.SPEventReceiverStatus.CancelWithRedirectUrl' is obsolete: '"Default list forms are committed through asynchronous XmlHttpRequests, so redirect urls specified in this way aren't followed by default. In order to force a list form to follow a cancelation redirect url, set the list form web part's CSRRenderMode property to CSRRenderMode.ServerRender"'. If you need to figure out how to set
CSRRenderMode.ServerRender property for the form automatically (in list definition), please refer to my
other blog post
SPUtility.Redirect - DOES NOT WORK
SPUtility.Redirect does not work in Event Receivers any more. It actually throws an exception. The reason - SPUtility.Redirect relies on HttpContext.Current, which does not exist at that point of execution. Tested with different CSRRenderMode settings.
[SubsetCallableExcludeMember(SubsetCallableExcludeMemberType.UnsupportedExternalType)]
public static bool Redirect(string url, SPRedirectFlags flags, HttpContext context, string queryString)
{
string urlRedirect = null;
bool flag = DetermineRedirectUrl(url, flags, context, queryString, out urlRedirect);
if (flag)
{
bool flag2 = SPRedirectFlags.DoNotEndResponse == (flags & SPRedirectFlags.DoNotEndResponse);
bool flag3 = DeltaPage.IsDeltaRedirectDisabled(context);
if (!flag3 && DeltaPage.IsRenderingDelta(context))
{
DeltaPage handler = context.Handler as DeltaPage;
if (handler != null)
{
handler.Redirect(context, urlRedirect, !flag2);
}
return flag;
}
bool flag4 = ((!flag3 && IsMDSEnabled(context)) && (!IsDialogUrl(urlRedirect) && IsBrowserRequest(context.Request))) && (SPRedirectFlags.AttemptMDSNavigate == (flags & SPRedirectFlags.AttemptMDSNavigate));
bool flag5 = false;
if (flag4)
{
flag5 = DeltaPage.AttemptMDSRedirect(context, urlRedirect, !flag2);
}
if (flag4 && flag5)
{
return flag;
}
SPLongOperation currentLongOperation = SPLongOperation.CurrentLongOperation;
if (currentLongOperation != null)
{
currentLongOperation.End(url, flags, context, queryString);
return flag;
}
if (Utility.IsClientQuery(context) && !Utility.IsRedirectAllowed(context))
{
RedirectException exception = new RedirectException(urlRedirect);
context.Items[typeof(RedirectException)] = exception;
throw exception;
}
try
{
context.Response.Redirect(urlRedirect, !flag2);
}
catch (Exception exception2)
{
if ((exception2 is ThreadAbortException) && !flag2)
{
throw;
}
ULS.SendTraceTag(0x62613371, ULSCat.msoulscat_WSS_Runtime, ULSTraceLevel.Medium, "Redirect to {0} failed. Exception: {1}", new object[] { url, exception2.ToString() });
}
}
return flag;
}
internal static bool IsMDSEnabled(HttpContext ctx)
{
return (((((ctx != null) && !DeltaPage.IsStartPage) && (!SPMobileUtility.IsMobilePageRequest(ctx, ctx.Request.Browser) && (ContextCompatibilityLevel >= 15))) && ((SPContext.Current != null) && (SPContext.Current.Web != null))) && SPContext.Current.Web.EnableMinimalDownload);
}
public static bool IsStartPage
{
get
{
return IsMDSStartPageUrl(SPAlternateUrl.ContextUri.AbsolutePath);
}
}
public static Uri ContextUri
{
get
{
return GetContextUri(HttpContext.Current); //Here it throws an exception
}
}
WORKING SOLUTION:
_currentContext.Response.Redirect
_currentContext.Response.Redirect does work though (IMPORTANT: Only when the form, which initiates an event, is being rendered in CSRRenderMode.ServerRender mode.) You can use the following sample:
public class TestEventHandler : SPItemEventReceiver
{
private readonly HttpContext _currentContext;
public TestEventHandler()
{
_currentContext = HttpContext.Current;
}
// Methods
public override void ItemAdding(SPItemEventProperties properties)
{
var url = new StringBuilder("test.aspx");
string urlRedirect = null;
bool flag = SPUtility.DetermineRedirectUrl(url.ToString(), SPRedirectFlags.RelativeToLayoutsPage, _currentContext, null, out urlRedirect);
_currentContext.Response.Redirect(urlRedirect, true);
}
}