Session is Null (No session at all) in class, but session does exist when accessing from aspx page - asp.net

I am working on a multi developer web app. I am trying to sort out an issue that came up with one dev not being able to access session variables in his custom classes.
I synced his changes, and the same issue happens on my dev machine. (I.e., its not IIS specific)
Upon further inspection, the session object completely disappears (there is no session, nto even an empty session with a session ID. Any attempt to access HttpContext.Current.Session throws a null reference exception.
Running the page code again after setting some session variables, shows the variable are all saved and acting normal in the session that I can access from the page itself . (The session object behaves as it normally does)
So to be clear, in the same process, debugging from page through to custom class, the session object is accessible in the page, not existing in custom class, and when returning to the page, its available again.
I have tried setting just a normal string session var to eliminate possible problems with my variable (object) stored in the session. The same issue persists.
Any ideas?

Alrighty then.. always helps to bounce it off a wall :-)
We were using a textbox autocomplete extender that was referencing our own custom webmethod, (inside our app in a custom class). It seem the webmethod decoration forced it to operate stateless... hence no session.
We moved this webmethod decorated function into our page-codebehind page, and it now calls the other custom classes "with" session object availability.

Related

How do I instantiate the Profile from an ashx file?

I recently switched some AJAX queries to use ashx files instead of aspx, having discovered that Response.End is no longer in vogue. In the case I'm looking at now, the submission of a purchase order is handled by the ashx. The user clicks the Submit button on the PO and the ashx file records the time and the user in a database table. An object with the current user's data (including their primary key) is stored in the Session and is recorded there by a custom Profile Provider. I have added IReadOnlySessionState in order to be able to access the Session, but it appears that, unless another .net page has been accessed, the Profile Provider doesn't run and the Session has no values. (verified by stepping through the code.)
I tried IRequiresSessionState, but the same results.
I'm assuming that the System.Web.UI.Page HttpHandler instantiates the custom Profile if it hasn't been already and that I'll need to add that to my custom HttpHandler.
I looked briefly at HttpModules, but I don't think that's what I want because they load for each request.
What is the value of HttpContext.Current.Profile? The Profile property is populated during the AcquireRequestState stage of the Request lifecycle by the built in HttpModule ProfileModule.
There is great info here http://odetocode.com/articles/440.aspx on how the internals work.

Glimpse - How do I access HttpContext.Session inside an IRuntimePolicy

I'm enjoying the Glimpse web diagnostics platform for ASP.NET, and would like to deploy it to production to capture data about end-user interactions to help with troubleshooting. Obviously I'd like to lock down access so not just anyone can access all the data Glimpse captures.
I've implemented GlimpseSecurityPolicy (an instance of IRuntimePolicy) and confirmed via a debug breakpoint that the Execute method is invoked when I request a page on my site.
The problem is that I can't interrogate the session associated with the current HttpContext. I'm able to get an instance of the context by calling policyContext.GetHttpContext()... but that context object has a null Session property. The property is also null if retrieved via HttpContext.Current.
When accessing the current context elsewhere in my main application code (via HttpContext.Current), the Session property is populated and I can interact with it just fine.
So I have two related questions:
Why is the Session property not populated?
How can I get access to the current Session from inside a Glimpse IRuntimePolicy?
If it helps, I'm running Glimpse 1.8.5 in a website running ASP.NET MVC 5.2. Also I've left the IRunTimePolicy ExecuteOn property returning the default return RuntimeEvent.EndRequest | RuntimeEvent.ExecuteResource;.
The reason is that your IRuntimePolicy is actually being executed to late in the pipeline. As you said, you kept the default value for the ExecuteOn property, and the session is closed before that RuntimeEvent.
If you change the value for ExecuteOn to RuntimeEvent.BeginSessionAccess | RuntimeEvent.ExecuteResource then the Session property should be available inside your IRuntimePolicy implementation.
Regarding the RuntimeEvent.ExecuteResource this one is only needed if your IRuntimePolicy is actually used to enforce resource access aka used for Glimpse Authorization, see this blog post for more details. So if that is not the case, then you can remove it as well.

asp.net serialization exception is thrown when implementing session in sql server

"serialization exception thrown in System.Web.Profile.DefaultProfile"
I'm using a lot of custom classes but have marked them all with serializable attribute. The website loads properly initially on the default page, but once a redirection happens to a different page, which inherits the custom "BasePage" class, instead of the default Page class, this exception is thrown :
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
one of the statements in the intellitrace says something like, "failed to serialize System.Web.Profile.DefaultProfile could not be serialized". Isn't it an inbuilt .NET object, and if so cannot I presume that it should be serializable in all cases???
I just ran into this same problem yesterday. The custom object isn't necessarily the problem, but objects inside of that. If you have things like System.Drawing.Image or Dictionary<> or anything else that isn't inherently serializable, its gonna blow up. So you're gonna have to do some digging. I had to do things like convert a List into a string[] to pass it to the web service (which receives a List but shows in intellisense as receiving a string[]).
So I'd rethink that. We also found out that once we got that working in the test server, we weren't done. As soon as we published the web service, other problems started popping up that were similar. Images were not serializable so we converted them to byte[] before sending them, Dictionaries were also not serializable.
I realize this isn't much of an answer, but hopefully of some help.
It is built into ASP.Net, but that doesn't mean it's serializable. There's lots of framework classes that are not serializable.
But also, the Default profile is made to work with the asp.net profile mechanism. Why are you attempting to store that in session? It already has it's own configurable storage mechanism. I think this may be a case where you're in a place where you're fighting the system.
For my particular case, I worked around the problem by creating a new custom class with a Serializable attribute, with a property that would return the HttpContext.Current.Profile object. And then whenever I needed to add the profile into session, I'm adding it through the property of this newly created class. Thanks to #swannee and #Sinaesthetic for their ideas.

Session information in .net (asp and webservice)

I'm making a .net component, resulting in a dll assembly, that will be referenced by an asp.net site, and in another project by an asmx webservice. All code is version 2.0.
The component has a few functions that call an external webservice, which returns an object. One of these functions is for example Login(username, password), which generates amongst others a unique session id for this user. The resulting information and session id are stored in variables in the component.
The issue in the website is:
When the user logs in in the frontend, and my component gets called and checks the login and generates the session id, I want that information in my component to persist when the user browses to another page in the site.
The issue in the web service using my component is:
I don't really care much about session state, but I want the component to just work. If per call a new session id is generated, that's okay.
The combination of the two environments causes the following problem for me:
I can't use the asp.net Session() variable in my component without referencing system.web, which is kinda silly and might not be available in the web service project that includes my component
I can't program my component as a singleton, because then in the website application, it's shared amongst all visitors, overwriting sessions and whatnot
making an array of "session information" in my component and maintaining that is hard to program (when does it get invalidated?) and might not work in a web farm environment
Is there a solution to this situation? Or should I make two instances of my component, one for use in websites, and one for use in web services?
Perhaps I'm not understanding what your asking but why can't you do something like:
Component.Login(user,pass);
Session["Component"] = Component.SessionID
I've created an extra class "Factory" which has a .Create(byref Session as HttpSessionState), that looks if the passed in session object is Nothing, if not, it checks if there is a Component object in it, if so, it uses it, if not, it creates it and adds it to the session.
In the case of the webservice call, the factory gets the Nothing-parameter, so it doesn't check in the session object. It seems to work.
Thanks for your answers!

What should I do if the current ASP.NET session is null?

In my web application, I do something like this to read the session variables:
if (HttpContext.Current.Session != null && HttpContext.Current.Session["MyVariable"] != null)
{
string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}
I understand why it's important to check why HttpContext.Current.Session["MyVariable"] is null (the variable might not have been stored in the Session yet or the Session has been reset for various reasons), but why do I need to check if HttpContext.Current.Session is null?
My understanding is that the session is created automatically by ASP.NET therefore HttpContext.Current.Session should never be null. Is this assumption correct? If it can be null, does it mean I should also check it before storing something in it:
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
// What should be done in this case (if session is null)?
// Is it possible to force the session to be created if it doesn't exist?
}
Yes, the Session object might be null, but only in certain circumstances, which you will only rarely run into:
If you have disabled the SessionState http module, disabling sessions altogether
If your code runs before the HttpApplication.AcquireRequestState event.
Your code runs in an IHttpHandler, that does not specify either the IRequiresSessionState or IReadOnlySessionState interface.
If you only have code in pages, you won't run into this. Most of my ASP .NET code uses Session without checking for null repeatedly. It is, however, something to think about if you are developing an IHttpModule or otherwise is down in the grittier details of ASP .NET.
Edit
In answer to the comment: Whether or not session state is available depends on whether the AcquireRequestState event has run for the request. This is where the session state module does it's work by reading the session cookie and finding the appropiate set of session variables for you.
AcquireRequestState runs before control is handed to your Page. So if you are calling other functionality, including static classes, from your page, you should be fine.
If you have some classes doing initialization logic during startup, for example on the Application_Start event or by using a static constructor, Session state might not be available. It all boils down to whether there is a current request and AcquireRequestState has been run.
Also, should the client have disabled cookies, the Session object will still be available - but on the next request, the user will return with a new empty Session. This is because the client is given a Session statebag if he does not have one already. If the client does not transport the session cookie, we have no way of identifying the client as the same, so he will be handed a new session again and again.
The following statement is not entirely accurate:
"So if you are calling other functionality, including static classes, from your page, you should be fine"
I am calling a static method that references the session through HttpContext.Current.Session and it is null. However, I am calling the method via a webservice method through ajax using jQuery.
As I found out here you can fix the problem with a simple attribute on the method, or use the web service session object:
There’s a trick though, in order to access the session state within a web method, you must enable the session state management like so:
[WebMethod(EnableSession = true)]
By specifying the EnableSession value, you will now have a managed session to play with. If you don’t specify this value, you will get a null Session object, and more than likely run into null reference exceptions whilst trying to access the session object.
Thanks to Matthew Cosier for the solution.
Just thought I'd add my two cents.
Ed
If your Session instance is null and your in an 'ashx' file, just implement the 'IRequiresSessionState' interface.
This interface doesn't have any members so you just need to add the interface name after the class declaration (C#):
public class MyAshxClass : IHttpHandler, IRequiresSessionState
In my case ASP.NET State Service was stopped. Changing the Startup type to Automatic and starting the service manually for the first time solved the issue.
ASP.NET Technical Articles
SUMMARY: In ASP.NET, every Web page
derives from the System.Web.UI.Page
class. The Page class aggregates an
instance of the HttpSession object for
session data. The Page class exposes
different events and methods for
customization. In particular, the
OnInit method is used to set the
initialize state of the Page object.
If the request does not have the
Session cookie, a new Session cookie
will be issued to the requester.
EDIT:
Session: A Concept for Beginners
SUMMARY: Session is created when user
sends a first request to the server
for any page in the web application,
the application creates the Session
and sends the Session ID back to the
user with the response and is stored
in the client machine as a small
cookie. So ideally the "machine that
has disabled the cookies, session
information will not be stored".

Resources