I am pretty new to .NET - I am making a site that has an admin section that should only be visible to logged in users.
I have created the login code and once a user is authenticated, I then assign them a session variable.
My question is : is there a more efficient way to check the session variable rather than having the following function on each page?
protected void Page_Load(object sender, EventArgs e)
{
checkSession();
}
public void checkSession()
{
if (Session["LoggedIn"] != "true")
{
Response.Redirect("default.aspx");
}
}
thanks kindly!
if you are using a MasterPage you can put the checking code in the MasterPage's Page_Load event if not use either the Global.asax or a custom HttpModule and put the cheking code inside the the AcquireRequestState event handler for the first and the PostRequestHandlerExecute event handler for the second
Exmaple with Global.asax
public class Global : System.Web.HttpApplication
{ ...
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
// CheckSession() inlined
if (context.Session["LoggedIn"] != "true")
{
context.Response.Redirect("default.aspx");
}
}
...
}
You should probably consider using forms authentication:
http://www.asp.net/web-forms/videos/authentication/using-basic-forms-authentication-in-aspnet
You can configure a page, or folder to always require authorization, so the runtime will take care of that requirement rather than you having to check manually.
You could make your page a class that inherits from a base class that checks for logged in users.
Derive your pages from a custom class that derives from Page
override the Load method by adding your session check code
now all your pages have the validation
public class MyPage : System.Web.UI.Page
protected void Page_Load(object sender, EventArgs e)
{
if (Session["yoursession"] != "true")
{
//code
}
}
public class yourCustomPage1 : MyPage
{
protected void Page_Load(object sender, EventArgs e)
{
//you don't have to check or call any method..
}
}
public class yourCustomPage2 : MyPage
{
protected void Page_Load(object sender, EventArgs e)
{
//you don't have to check or call any method..
}
}
etc...
A good way to start to understand forms authentication in ASP.Net is creating a brand new website.
Go in Visual Studio and create New Project, select Web, then ASP.NET Web Application.
Check it out in Account folder to understand the process and ASP.Net methods.
You can create BasePage and inherit all your page from this base page , set the function in your basepage.
public class BasePage : Page
{
protected void checkSession()
{
if (Session["LoggedIn"] != "true")
{
Response.Redirect("default.aspx");
}
}
}
Your Page
public partial class YourPage : BasePage
{
....
}
Another solution :
In your Http Module, create Principal(Roles) and Identity in order to set authentification and authorization functionnalities, in your http module attach theses informations to current thread.
link : http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.isauthenticated.aspx
public class BasePage : Page
{
protected void checkSession()
{
if (Session["LoggedIn"] == null)
{
Response.Redirect("~/default.aspx/");
}
}
}
1st Way : Global.asax.cs ADD
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
Page page = context.Handler as Page;
if ((string)context.Session["LoggedIn"] != "true"
&& !(page.AppRelativeVirtualPath == "~/Default.aspx"))
context.Response.Redirect("default.aspx");
}
2nd Way : You can have the same session management in Master page. Page Load event.
Hope this helps.
You can add this code in the GLOBAL.asax.cs this will check if the session is empty and also it will not redirect if this the request is initialized from the Login page otherwise it will stuck in a loop.
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
// CheckSession() inlined
if (Context.Request.Url.LocalPath != "/UIComponents/User/Login.aspx")
{
if (context.Session["Name"] == null)
{
FormsAuthentication.RedirectToLoginPage();
}
}
}
Related
EDIT: made variables not-static.
I have a variable in code-behind class and want to access it from another.
Here's the C# code for the "Signup" page:
public partial class Webform_Signup : System.Web.UI.Page
{
private string user;
public string User
{
get { return user; }
set { user = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if(HttpContext.Current.Request["submit"] != null)
{
user = HttpContext.Current.Request["user"];
Response.Redirect("Login.aspx");
}
}
}
And here's the code for another code-behind class in an .aspx class "Login":
public partial class Webform_Login : System.Web.UI.Page
{
public string loguser = "";
protected void Page_Load(object sender, EventArgs e)
{
if(HttpContext.Current.Request["logsubmit"] != null)
{
loguser = HttpContext.Current.Request["loguser"];
if (loguser == Webform_signup.User)
{
Response.Redirect("Start");
}
}
}
}
The problem is that when I try to access Webform_signup.user, it displays an error saying:
The name Webform_Signup does not exist in the current context.
Anyone has an idea of how to fix it?
The dirt simplest way (and probably not the best way) is to just stick it in a session variable and read it from there instead.
public partial class Webform_Signup : System.Web.UI.Page
{
private string user;
public string User
{
get { return user; }
set { user = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if(HttpContext.Current.Request["submit"] != null)
{
user = HttpContext.Current.Request["user"];
HttpContext.Current.Session["user"] = user; //Save to session
Response.Redirect("Login.aspx");
}
}
}
public partial class Webform_Login : System.Web.UI.Page
{
public string loguser = "";
protected void Page_Load(object sender, EventArgs e)
{
if(HttpContext.Current.Request["logsubmit"] != null)
{
loguser = HttpContext.Current.Request["loguser"];
var user = HttpContext.Current.Session["user"]; //Read from session
if (loguser == user)
{
Response.Redirect("Start");
}
}
}
}
This is assuming of course that you have session state enabled.
You need to keep in mind lifecycles. You're ignoring them, and the results would be disastrous in this case.
Any time you declare a variable as static, there will only be one instance of that variable in your application. That means no matter what user is using your app, the Webform_Signup.User field will be shared. That could result in users accessing other users' information! That's really, really bad.
Also, page classes should not be referring to other page classes. A page only exists when a user is accessing that page.
If you want to login a user, then perhaps you should research Forms Authentication. Or better yet, learn a modern framework like ASP.NET Core MVC instead of Web Forms, which is a deadend platform.
I have a Webhandler which generates an image on request in my asp.net Project. But if the user directly access the resource, it won't trigger the session start Event in the Global.asax file. But in my project I need to trigger the session start event. How can I achieve this?
void Session_Start(object sender, EventArgs e)
{
Session["Test"] = 1;
}
The Session_Start event is trigerred whenever some server side handler attempts to either read or write to the session. You might try decorating your handler with the IRequiresSessionState marker interface:
public class MyHandler: IHttpHandler, IRequiresSessionState
{
...
}
You can always make a method of the Session_Start and call it
namespace WebFormsApplication1
{
public class Global : HttpApplication
{
void Session_Start(object sender, EventArgs e)
{
Global.StartSession();
}
}
public static class Global
{
public static void StartSession() {
Session["Test"] = 1;
}
}
}
and in your Handler, simply call Global.StartSession();
I'm using ASP.Net 4 (Visual Studio 2010 - C#). My session keeps expiring on postback.
I am setting my session variable in the Page_Init method of the MasterPage. The issue is not a timeout problem.
ASP.NET fails to detect IE10.. please check this..
http://www.hanselman.com/blog/BugAndFixASPNETFailsToDetectIE10CausingDoPostBackIsUndefinedJavaScriptErrorOrMaintainFF5ScrollbarPosition.aspx
looks like issue with post back... how are u doing postback...could you please add details..
public partial class MasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if(Session["abc"] == null)
Session["abc"] = "abcd";
}
}
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
string x = Session["abc"] as string;
Response.Write(x);
}
}
I have been trying to find a good answer to this question, but can't seem to find one. I have an ASP.NET page that derives from a base page, like this:
public partial class MainPage : MyBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
var loginTime = GetLoginTime(); // This works fine
}
}
And the base page:
public partial class MyBasePage: Page
{
}
protected DateTime GetLoginTime()
{
// Do stuff
return loginTime;
}
Now I have a user control on that page that needs to call my method...Like this:
public partial class TimeClock : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var loginTime = GetLoginTime(); // This does not work!
}
}
As you can see, I cannot call my base method, for obvious reasons. My question is, how can I call this method from my user control? One work around I've found is like this:
var page = Parent as MyBasePage;
page.GetLoginTime(); // This works IF I make GetLoginTime() a public method
This works, if I make my function public instead of protected. Doing this doesn't seem like a very OOP way to tackle this solution, so if someone can offer me a better solution, I'd appreciate it!
TimeClock inherits from UserControl, not from MyBasePage so why should TimeClock see the Method GetLoginTime()?
You should keep your UserControl out of your Page stuff. It should be decoupled in OOP speak. Add properties to set values and delegates to hook into events:
public partial class TimeClock : UserControl
{
public DateTime LoginTime{ get; set; }
public event UserControlActionHandler ActionEvent;
public delegate void UserControlActionHandler (object sender, EventArgs e);
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button_Click(object sender, EventArgs e)
{
if (this.ActionEvent!= null)
{
this.ActionEvent(sender, e);
}
}
}
Page
public partial class MainPage : MyBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
var loginTime = GetLoginTime();
TimeClock1.LoginTime = loginTime;
TimeClock1.ActionEvent += [tab][tab]...
}
}
(this.Page as BasePage).MethodName()
Why DisplayUsers(); doesn't work?
My base page is:
public class adminPage : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
if (User.Identity.IsAuthenticated == false) { Response.Redirect("~/Account/login.aspx?ReturnUrl=/admin"); };
if (!(User.IsInRole("admin") || User.IsInRole("super user"))) { Response.Redirect("/"); };
}
}
my class is
public partial class users : adminPage
{
protected void Page_Load(object sender, EventArgs e)
{
string sName;
adminGeneralData.GetToolData(2, out sName);
pageH1.Text = sName;
DisplayUsers();
}
protected void DisplayUsers()
{
DataSet ds = userData.GetUsersData();
userList.DataSource = ds;
userList.DataBind();
}
}
but DisplayUsers() doesn't work,
If I recall correctly, you'll need to call the base class's OnLoad event to register the Page_Load event properly:
protected override void OnLoad(EventArgs e)
{
if (User.Identity.IsAuthenticated == false) { Response.Redirect("~/Account/login.aspx?ReturnUrl=/admin"); };
if (!(User.IsInRole("admin") || User.IsInRole("super user"))) { Response.Redirect("/"); };
base.OnLoad(e);
}
Here are a couple of good reads:
OnLoad vs. Page_Load vs. Load event
When creating a web control should you override OnLoad or implement Page_Load
According to Performance Tips and Tricks in .NET Applications:
Avoid the Autoeventwireup Feature
Instead of relying on autoeventwireup, override the events from Page. For example, instead of writing a Page_Load() method, try overloading the public void OnLoad() method. This allows the run time from having to do a CreateDelegate() for every page.
In the code executed, there is no difference, but
AutoEventWireup should be enabled (usually in markup) for each page
Page_Load (and other events like this) uses automatic events subscription mechanism, which uses Reflection, what slightly hits performance
I personally recommend to override OnLoad(), just don't forget to call base.