I’ve seen a lot of posts saying you can’t redirect to a custom error page from a SPItemEventReceiver in SharePoint 2007.
In 2010, you can use Properties.RedirectUrl which will send you to a custom error page, instead of the OOB error page that displays your properties.ErrorMessage. this is simple enough, all you have to do is set properties.Cancel = true – and the custom redirect Url kicks in.
But still, in 2007 this property does not exist, and in 2010 – you might want to have a custom redirect page and not cancel the event.
Good news – it is all possible!
The way to do it, is to add some code to a sync event. Async events can’t help you since they are not guaranteed to run immediately, and they don’t have any user context when they execute…
You can use the SPUtility.Redirect(PageUrl, SPRedirectFlags, HTTPContext); within your ItemAdding, ItemUpdating or ItemDeleting event handler to redirect your user to a custom page.
This redirection kicks in and throws the “ThreadAbortException”, stopping the rest of your code from running and redirecting the user to your custom page.
Few things to know:
1. ThreadAbortException is a “catch me if you can” exception. you can put it in try…catch… block, but this exception will always bubble up and be thrown again and again. essentially, only the catch and finally code blocks will run after this exception is thrown. you can set “SPRedirectFlags.DoNotEndResponse” if you don’t want this exception to be thrown and it should still redirect at the end, but using SPRedirectFlags.Default will throw it.
2. You may notice, that if you try using HTTPContext.Current in your event handler method – you will get a null context. So, the only way to get the HTTPContext.Current is in your event handler class constructor. save it as a member, and use it in your event handlers. DONT SAVE IT AS A STATIC MEMBER! Use any instance member (private/public/protected…) but don’t use a static member as you may run into unexpected trouble.
Cancelling the event
Now, we took care of redirecting, but it is good to remember that this on its own will not cancel the item event and it will still be updated/added/deleted.
If you want to cancel the item event, you still have to do that using properties.Cancel = true.
Since we talked about ThreadAbortException – now you know you have to put the SPUtility.Redirect code in a try block, and set the properties.Cancel in the catch block.
Your code should look like this:
SPUtility.Redirect("/_layouts/KWizCom/AppError.aspx?ErMsg=" + errMessage, SPRedirectFlags.DoNotEndResponse, currentContext);
properties.ErrorMessage = errMessage;
properties.Cancel = true;