Reputation: 415
So I read up a lot about how to properly use Response.Redirect without causing some errors.
Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();
Situation: A user logs in the site and visits a page that lists forms. The user sits on that page for an hour doing nothing (which would log them out). The user clicks a button to edit a title (which requires a postback). This results in the user object being null since it logged him out of the session.
What I have done: In the page load, check if the user object is null and if it is, redirect to the login page. That is what should happen right?
Problem: The button event is STILL firing. Is it because I have the following line of code?
Context.ApplicationInstance.CompleteRequest();
How can I stop the event from being firing when I simply want to redirect to the login page?
I know I can provide true in the redirect code, but that will cause an error too right?
Response.Redirect(url, true);
What I currently do (which is not the best way I know): In the button event, I again check to see if the user object is null. If it is not null, proceed with the code to edit the title (recording who edited it). This is a bad way of handling this.
What I have seen: Wrap all events with Response.IsRequestBeingRedirected. But if I have several pages and lots of button events, this can get a bit annoying. Is this the only way to handle this situation?
Example:
protected void Page_Load(object sender, EventArgs e)
{
Account account = Session["Account"] as Account;
if (account == null)
{
Response.Redirect("WebForm1.aspx?NewSession=true", false);
Context.ApplicationInstance.CompleteRequest();
return;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Account account = Session["Account"] as Account;
Label1.Text = account.userID.ToString();
}
Again, if I am already on the page, and the session expired, and I click Button1, the Button1_Click method is still being called. What I provided will give me a "NullReferenceException". Page_Load IS being called, and it is making the redirect. However, Button1_Click is still being called even with the return statement in Page_Load.
Thanks!
Upvotes: 4
Views: 4504
Reputation: 3203
You are correct about Response.Redirect(url, true)
. It is kind of expensive because it throws ThreadAbortException
causing the current thread to terminate which is not what you want most of the times.
There is even a KB exists on this topic KB312629.
And yes, with your code it is not possible to prevent events from firing for the current IHttpHandler
(which Page
class implements) using built-in classes/methods.
So I would suggest to create base page class and add a bool
field indicating about request completion request plus method that will call ApplicationInstance.CompleteRequest
and will set the flag to true
. Also you'll need to override RaisePostBackevent
method to take control over controls (not Page) events invocation on page.
public abstract class BasePage : Page
{
private bool shouldNotRaiseEvents;
protected void CompleteRequest()
{
shouldNotRaiseEvents = true;
Context.ApplicationInstance.CompleteRequest();
}
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (shouldNotRaiseEvents)
{
return;
}
base.RaisePostBackEvent(sourceControl, eventArgument);
}
}
Your updated code would be:
Response.Redirect(url, false);
CompleteRequest();
Also please note that if you have something inside LoadComplete
, PreRender
, SaveViewState
, Render
, Unload
event handlers and you don't want this code to execute after redirect call you'll need to override that methods also.
Upvotes: 3