Why does HttpContext.Current need to used within a class, but not a method - asp.net

For instance if I'm inside the Page_Load method and I want to get query string data I just do this:
public partial class Product_Detail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string id = Request.QueryString["p"];
}
}
but if I am inside the class, but not within any method I have to use:
public partial class Product_Detail : System.Web.UI.Page
{
string id = HttpContext.Current.Request.QueryString["p"];
protected void Page_Load(object sender, EventArgs e)
{
}
}
Why is that?

Member variable initialisers - which is what your id assignment is -- can't use instance methods or properties. Page.Request is an instance property, and therefore isn't available to member initialisers.

I would surmise it is because class members are not created until the class is instantated. Because of this you cannot access the Request property except within your class methods.

Properties of the current class (including this) are not accessible until the constructor. Since field initializers happen before the constructor is executed, properties (and fields, and methods) are not accessible.

You cannot refer to an instance's properties for a field's initializer—when the field is initialized the instance isn't fully constructed yet (i.e., there's no this pointer).

Related

HttpContext.Current.Session Is Null In Global.asax

I used forms authentication.
In LdapAuthentication.cs I have property
public static string ReturnProject
{
get
{
return HttpContext.Current.Session["Project"].ToString();
}
}
In global.asax.cs I trying to get Session["Project"] from LdapAuthentication.cs for check and ridirect to other pages according with rusult in Session["Project"], but I've got System.NullReferenceException. I cheked Session["Project"] in LdapAuthentication.cs - is ok
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Request.AppRelativeCurrentExecutionFilePath == "~/")
{
if (LdapAuthentication.ReturnProject == "Team Leader")
HttpContext.Current.RewritePath("~/TLPage.aspx");
else
if (LdapAuthentication.ReturnName == "ccobserver")
HttpContext.Current.RewritePath("~/ScheduleReport.aspx");
else
HttpContext.Current.RewritePath("~/PersonPage.aspx");
}
}
doesn't matter which handler use Application_AcquireRequestState or Application_AuthenticateRequest.
Thanks!
You declared ReturnProject static property, while HttpContext is an instance property of HttpApplication class, implemented in Global.asax.
Static property has no access to instance properties, so removing static modifier from ReturnProject should fix the problem.
EDIT
Now I get it, ReturnProject property declared in LdapAuthentication.cs, not in Global.asax.
Let me explain a bit. Every time request hits a server, new instance of HttpApplication (hence, HttpContext instance property) is created. This way you get access to Request and Session — they are bound to concrete request associated with concrete user. Related answer: “HttpContext.Current.Session” vs Global.asax “this.Session”
What you seem trying to achieve is to pass some session variable (Project) to the LdapAuthentication class in a nice way. There are more than one way to do this, but the obvious way without looking to the source of LdapAuthentication class is to add LdapAuthentication instance field to the Global.asax, passing session variable through the constructor or property initializer. Something like this:
LdapAuthentication.cs
/// <summary>
/// Creates instance of LdapAuthentication with Project value initialized
/// </summary>
public LdapAuthentication(string project) {
this.ReturnProject = project;
}
Global.asax
private LdapAuthentication auth = new LdapAuthentication(
HttpContext.Current.Session["Project"].ToString()
);
...
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Request.AppRelativeCurrentExecutionFilePath == "~/")
{
if (auth.ReturnProject == "Team Leader")
HttpContext.Current.RewritePath("~/TLPage.aspx");
else
if (auth.ReturnName == "ccobserver")
HttpContext.Current.RewritePath("~/ScheduleReport.aspx");
else
HttpContext.Current.RewritePath("~/PersonPage.aspx");
}
}

Ajaxpro methods get global page variable to be reinitialized?

I have a problem with ajaxpro methods. In the .cs file I defined some global variable for my page, something like:
public partial class Admin : System.Web.UI.Page
{
public int localidMember = 9;
protected void Page_Load(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax(typeof(Admin));
if (HttpContext.Current.Session["HomeOwn_ID"] != null)
{
localidMember = Convert.ToInt32(HttpContext.Current.Session["HomeOwn_ID"].ToString());
}
}
[AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.ReadWrite)]
public string LoadInbox()
{
// I need to use the variable localidMember and expected that it will have the value that I have set to pageload.., but it didnt. The variable is reinitialized to 9... Anyone have any ideas what's going on... Thanks so much !
}
}
I think you can't do it; because, in AjaxPro, you can't deal with control properties.
AjaxMethod will have its own Context. Hence, localidMember will not be accessible inside it. You may consider passing it as a parameter.

Strange Guid.NewGuid() behaviour

I have searched the site for an answer to this question, but I cannot seem to figure this one out.
I have use the NewGuid() method many times and it has worked greate. But now for some reason it creates an empty Guid.
Here is my code:
// Class of the Guid Object
public class CardUserAccount
{
// User ID of the user's profile
public Guid UserId { get; set; }
}
//Page object where method is called
Public partial class CreateSale : System.Web.UI.UserControl
{
// Create the UserProfile object
public CardUserAccount profile = new CardUserAccount();
protected void ContinueButton_Click(object sender, EventArgs e)
{
Guid _userId = Guid.NewGuid();
profile.UserId = _userId;
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
// Method to add object to database
SubmitProfile(profile);
}
I then call a simple linq to entities method to add the object to the entity object.
I have double checked it and I am not overwriting it anywhere.
However could it be a problem that I am creating the profile object outside of the page_load method. I thought this would not affect the object during postback.
I would appreciate the help
Is this actual code? Because you declare and initialize the variable, then do nothing with it.
If you intend to overwrite a field value, you should not declare that field inside this method.

Callling business logic layer method from PageMethods

I've a static page method in web form application and I want to call method on private class level variable from it as shown below. I'm using jQuery to call the page method.
private readonly ICatalogBLL _catalogBLL = new CatalogBLL();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_catalogBLL.GetSomething();
}
}
[WebMethod]
public static UpdateSomething(int i)
{
//Want to do as below. But can't call it from a static method.
_catalogBLL.UpdateSomething();
}
UPDATE
If I call it as said by John Saunders, won't it use the same instance for requests from different users as it is within a static method?
You can't. The page method is static. Your _catalogBLL is an instance member.
However, since you create a new instance of CatalogBLL on every request, why not do so once more?
[WebMethod]
public static UpdateSomething(int i)
{
CatalogBLL catalogBLL = new CatalogBLL();
catalogBLL.UpdateSomething();
}
You can't call because pagemethods are static...
A static method is simply one that is disassociated from any instance of its containing class. The more common alternative is an instance method, which is a method whose result is dependent on the state of a particular instance of the class it belongs to.
Look at John saunder's answer..

Separation of concerns in asp.net cause hierarchy mess

I’m designing a back office web site, one that will enable administrators to manage content, products, prices and such. I have two issues I’d like to solve in a base class that each page controller (i.e. code-behind class) will extend, and these are:
Storing of ViewState on disk, and
User validation.
Furthermore, I would like each page controller to follow the same design when it comes to setting event handlers, populating the form and saving the data. I would like to solve this issue by creating abstract methods that the page controllers implement.
Now, creating a base class that caters for ViewState storage and user validation, and furthermore defines how and when event handlers are set, forms are populated and data is persisted to me is too much of a mess. I like a high degree of separation of concerns and I’m drawn towards creating three base classes:
System.Web.UI.Page
|
FileSystemStatePage : System.Web.UI.Page
(storing of ViewState)
|
SecurePage : FileSystemStatePage
(user validation)
|
PageBase : SecurePage
(abstract, defines methods for setting event handlers, form population, saving)
Now I am quite happy with the separation of concerns, but I’m not thrilled about the deep class hierarchy. What if I find myself in the need of user validation but not ViewState on disk? So...
...how do you guys usually solve these issues?
public class FileSystemStatePage : Page
{
protected override void SavePageStateToPersistenceMedium(object viewState)
{
// Serialize ViewState...
// Save to disk...
}
protected override object LoadPageStateFromPersistenceMedium()
{
// Read file content...
// Deserialize and return...
}
}
public class SecurePage : FileSystemStatePage
{
protected override void OnInit(EventArgs e)
{
if (!ValidateUser()) Response.Redirect("~/Login.aspx");
base.OnInit(e);
}
protected virtual bool ValidateUser()
{
return LoginHelper.LoggedInSystemUser != null;
}
}
public abstract class PageBase : SecurePage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
SetEventHandlers();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
Populate();
}
}
protected abstract void SetEventHandlers();
protected abstract void Populate();
protected abstract void OnCancel(object sender, EventArgs e);
protected abstract void OnSave(object sender, EventArgs e);
}
I'd have to say, with no particular solution, that a good separation of concerns is actually disrupted in the above nested hierarchy. It appears that the functional pieces should be further separated as to not be included every time the other is needed.
Why is it necessary that you have viewstate and validation in the same space? Why not separate it altogether?

Resources