asp.net: where to put code to redirect users without a session to the homepage?
I have a web app with loads of pages and most of them require some session variables in order to function.
i want to put some defensive code in my app. where is the best place to 开发者_开发知识库put somethign like:
if (Session.Count == 0){
Response.Redirect("~/default.aspx");
}
EDIT: how do i check if the current page is defult.aspx?
Quite difficult, yeah fortunately it is solved.
You need to implement Application_PreRequestHandlerExecute in Global.asax
here is the code
/// <summary>
/// The event occurs just after Initialization of Session, and before Page_Init event
/// </summary>
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
// here it checks if session is reuired, as
// .aspx requires session, and session should be available there
// .jpg, or .css doesn't require session so session will be null
// as .jpg, or .css are also http request in any case
// even if you implemented URL Rewritter, or custom IHttp Module
if (Context.Handler is IRequiresSessionState
|| Context.Handler is IReadOnlySessionState)
{
// here is your actual code
// check if session is new one
// or any of your logic
if (Session.IsNewSession
|| Session.Count < 1)
{
// for instance your login page is default.aspx
// it should not be redirected if,
// if the request is for login page (i.e. default.aspx)
if (!Context.Request.Url.AbsoluteUri.ToLower().Contains("/default.aspx"))
{
// redirect to your login page
Context.Response.Redirect("~/default.aspx");
}
}
}
}
Edit 1: Explanation & Conclusion
As one of the guys told about ASP.NET Application Life Cycle.
There are plenty of events that occurs.
Actually events in Global.asax raises in the following sequence
- Validate Request // looks just internal mechanism
Perform URL Maping // looks just internal mechanism
Raise the BeginRequest event.
- Raise the AuthenticateRequest event.
- Raise the PostAuthenticateRequest event.
- Raise the AuthorizeRequest event.
- Raise the PostAuthorizeRequest event.
- Raise the ResolveRequestCache event.
- Raise the PostResolveRequestCache event.
- Just selects a class who implemented IHttpHandler for the application // looks just internal mechanism
- Raise the PostMapRequestHandler event.
- Raise the AcquireRequestState event. just before raising this event asp.net loads the State like Session
- Raise the PostAcquireRequestState event.
- Raise the PreRequestHandlerExecute event.
- Call the ProcessRequest method
Conclusion: All the events before AcquireRequestState event don't have Session object, because Session is not loaded by ASP.Net, so any event from *"AcquireRequestState** event gives Session object therefore this problem solves. However some checks are required as I mentioned in above code
One method would be to have a Page baseclass that performs this check on Page_Init
. Another method would be to piggy-back off of @K Ivanov's idea with putting it in the Global.asax
. While Session is not available during Application_BeginRequest
it should be available in the method Application_AcquireRequestState
. For not standard web requests, this should provide access to the session to perform what you want.
in the Application_BeginRequest
of the Global.asax
so to summaries the ideas we have:
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if ((Session.Count == 0) &&
!(Request.Url.AbsolutePath.EndsWith("default.aspx",
StringComparison.InvariantCultureIgnoreCase)))
{
Response.Redirect("~/default.aspx");
}
}
Be careful with your approach. I don't think it is a good idea to validate globally if certain Session information exists or not. It can get become very messy, very fast. Only certain pages might require specific Session variables, which differ from other pages. Further down the road you might even have some content which can be safely accessed without any existing Session state. Then you will have to start coding exceptions to your rule...
What type of information are you storing in these Session variables? If you elaborate further we could maybe come up with a better approach.
Be careful with Session.Count == 0
, because things like Session_ID are, implicitly, stored in the session.
Preferably look for something like (Session["UserName"] == null)
, where Session["UserName"]
is where you, explicitly, store something of the user.
Other than that, Global.asax is the best place (ASP.NET Application Life Cycle).
ALSO, you have to enter a check that you are not currently on ~/default.aspx, because otherwise you will have an infinite loop.
精彩评论