I have a log in page and a content page (i.e. Home page).
If the user has not logged in, s/he will be redirected to the login page. At the login page, after the user has successfully logged in, the credential will be stored in a Session variable.
My question is, what would be the difference if I check the login status during the PreInit and Page_Load? i.e.
What is the difference between this:
protected void Page_PreInit(object sender, EventArgs e)
{
//If the user is not logged in, redirect the user to login page
if (Session["isLogin"] == null || Session["isLogin"] == 0)
{
Response.Redirect("~/Login");
}
}
and this:
protected void Page_Load(object sender, EventArgs e)
{
//If the user is not logged in, redirect the user to login page
if (Session["isLogin"] == null || Session["isLogin"] == 0)
{
Response.Redirect("~/Login");
}
}
Which of these is the more recommended way of implementing it? Pros and Cons?
For your purpose it's better to use the Page_PreInit event because you'll avoid to load unnecessary controls and viewstate that you're not going to use if the redirection is called.
You can find a good description of page events, what is loaded in the page and what you can control on each stage here
Related
I have a masterpage, contentplaceholder and an .ascx page.
The user enters his username-password at Masterpage.
I want to prevent the load of the contentplaceholder, if the user enters wrong username&password combination. Currently I am just disabling it's visibility, which does the trick but the page is still loaded, goes to database etc. which is useless since all of them will not be shown anyway.
You can load the Controls dynamically.
private WebUserControl1 userControl;
protected void Button1_Click(object sender, EventArgs e)
{
if (loginOK == true)
{
buildControls();
}
}
private void buildControls()
{
userControl = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
PlaceHolder1.Controls.Add(userControl);
}
Dynamically added controls need to be recreated on every Page_load
(that includes PostBack). So always call buildControls() when a user
is logged in.
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!
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.
I have the below code
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//do something
}
else
{
// do something else
}
}
protected void Button1_Click(object sender, EventArgs e)
{
//do something
}
}
The point is that a post back happens if I press F5/refresh button or a button click. How will I prevent the code from doing any action if F5/refresh button is clicked?
I have checked Detect F5 being pressed and Refresh but the solution of mine will be different as I need to do this in C# code.
Thanks
You are trying to capture something on the client - so it must be client side script (as discussed in the link).
It's not a postback in ASP.Net terms - your page is simply being requested again (GET). You cannot stop this - its just like going to some other page on your web site and clicking back through some navigation.
If you are saying you want to prevent some type of server side code you have from being run (more than x times) then you can think about sessions or cookies and read them in before you run whatever process. A simplistic sample:
visit page 1 - set session or cookie that identifies page 1 process was run
visit page 2 - set session or cookie that identifies page 2 process was run
return to page 1 - check for existence of session or cookie variable, and if exists, don't run page 1 process.
Another option, if viable is to use ASP.Net caching.
I want to redirect back to the home page when there is no activity.
However, i dont have a user login or the need to have one. However, i want to be able to redirect back to the home page when theres no activity.
I set this in the web.conf
<system.web>
<sessionState mode="InProc" timeout="2">
then, i set this in the homepage
Session["UserId"] = 1;
I also tried this but the function doesnt even fire.
protected void Page_Init(object sender, EventArgs e)
{
CheckSession();
}
private void CheckSession()
{
if (Session["UserId"] == null)
{
Response.Redirect("KioskHome.aspx");
}
}
Could i use the global.asax file?
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
}
void Session_End(object sender, EventArgs e)
{
}
What is the simple solution? Thank you
If I understand your question, you want to redirect the user's browser if the user hasn't performed any action in some period of time.
In that case - server-side behaviour won't help you. The connection has already closed. The global.asax Session_end will fire when the session is ending, and there won't be a client connected at that time.
Perhaps you should read more about the ASP.NET Page Lifecycle.
What you may want, however, is some form of client-side behavior such as Javascript, which after a specific timeout, can redirect the user.
Note that there's a number of issues with this, including that a user may use multiple tabs, so knowing accurately when the session has timed out is difficult.
I have a masterpage and inside that masterpage I have to check if a session is null or not. If the session is null, then there has to be a redirect to a login page.
That is no problem, but the problem is that the masterpage also have controls using the session and the child also uses the session so I get a nullreferenceexception.
I now have this:
protected void Page_init(object sender, EventArgs e)
{
var session = (ServiceSession)Session["serviceSession"];
if (session == null)
{
Response.Redirect("login.aspx", false);
}
}
But the problem is that the controls on the masterpage are also called instead of redirecting immediatly.
So the main question:
How can I redirect immediatly, without loading further things. Because the page_init gets called as first method the redirect should solve my nullreferenceexception, but than I don't need to load all components etc.
Thanks in advance!
Have you tried setting the second param of your Response.Redirect to true to halt the execution of the page?
You can use the Page_PreInit for this
private void Page_PreInit(object
sender, EventArgs e)
{
Response.Redirect("login.aspx", false);
}