Regarding the usage of IRequiresSessionState - asp.net

please tell me why IHttpHandler need to implement IRequiresSessionState. without implementing it we can not read/write anything in session variable?
can't we access directly HttpContext.Current.session like this way.
please explain.......thanks
public class MyHttpHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
var MyValue = context.Session["MyKey"] as String;
MyValue = "Hello World";
context.Session["MyKey"] = MyValue;
}
public bool IsReusable
{
get { return true; }
}
}

The session state is not a native part of the HTTP infrastructure. This means that the request will need to serialize/load the session information (either from memory or database or another server) for requests that need access to session and save it back when done.
HttpHandler is a the process (frequently referred to as the "endpoint") that runs in response to a request made to ASP.NET http runtime. It is used to handle a particular type of object/class/resource as you define it. If processing of that resource does not need access to session, that particular request does not need to go through the loading/saving of session data unnecessarily. So, by default, session is not available for HTTPhandlers, unless it is a predefined handler like Page handler.
To successfully resolve any call to the Session object, the runtime environment must add the session state to the call context of the request being processed, which is IRequireSessionState in this case.
Check out this msdn link for more details.
To answer your question, no, if you dont implement the IRequireSessionState, you will not have access to the session objects in your handler class due to the above mentioned facts.

If you do not implement this interface you should not be able to successfully use the session object. You are supposed to use this interface if you want access to the session, regardless of how you access it.
It shouldn't work without it. If it does, its a fluke and don't rely on it.

The ASP.NET SessionStateModule will not populate the context's session properties unless the handler is marked with the IRequiresSessionState interface.

Related

Disposing Com object in ASP.net application

I have a com dll built in .net and referred it as a interop.mycomlib.dll in my ASP.NET application. I initialize a class in the com object then call some functions and finally when the user signs off or closes the browser I release the com object.
Below is the code I am using. Initially, for the first user, the InitInstance() is called but when the user signs off the ExitInstance() of the com is not called.
If any other user signs on the InitInstance() is not called again because the same instance of com object is used for all the users. ExitInstance() is called only when an iisreset is performed or the w3wp process is terminated.
Is this the default behavior of how com interop works with asp.net, or is there something I am missing to do to completely dispose the com object?
public class ComFacade : IDisposable
{
public ComFacade()
{
myComObj_ = new MyCOMLib.MyClientClass();
}
..............................
public void Dispose()
{
Dispose(true);
myComObj_ = null;
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
try
{
Marshal.ReleaseComObject(myComObj_);
}
catch (Exception ex)
{
throw;
}
}
this.disposed = true;
}
}
}
Thanks
You don't mention what the scope of the variable containing the ComFacade instance is. If the variable is static then this would be the behavior I would expect.
I would suggest you understand the ASP.NET page lifecyle and the implications of that with variables of different scopes. Unless the COM reference is supposed to be a singleton then you will need to create a new instance each time the page loads and dispose of it as appropriate (probably when the page is rendered).
Update (based on comment)
Note: This answer applies to any object in .NET that you try to keep around longer that a single page request. Eventually all objects are disposed / garbage collected.
You mention that the object is created when the user logs in and disposed when they log off. The only way you could do this is to cache the object in something static to keep reference to it. Keep in mind that every time the user does something in their browser a request goes from the browser back to IIS/ASP.NET for processing and invokes a page life-cycle (over-simplification, but good enough). Each time the user does this the page may be handled by a different thread in the App Pool each time. If more than one user is interacting with the site then over a period of time the same thread may (and most likely will) get used by more than one user. In short this is why with ASP.NET/IIS you must be extremely cautious with using singletons / static members.
On a side note, my question would be why do you need a reference to the COM object for more than a single page request?

Forcing HttpHandler to use SessionState

I am trying to customize a vended product that routes all requests through a HttpHandler. The handler analyzes the request to figure out what page to route the user to and performs a Server.Transfer(). Unfortunately, I need to access SessionState on a page and the handler doesn't implement IRequiresSessionState and is marked as internal so I can't inherit from it. After a lot of googling the best solution I found was to create an HttpModule that changes the handler that processes the request at different points in the request lifecycle. On PostMapRequestHandler I would change the handler that processes the request to my own that implements IRequiresSessionState and PostAcquireRequestState I would map it back.
This works but does anyone have a better solution?
I figured out a more elegant way to enable session state. You can override the session state behavior of a handler. I created a module that forces session state.
public class SessionEnablerModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostMapRequestHandler += new EventHandler(context_PostMapRequestHandler);
}
void context_PostMapRequestHandler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
if ((app.Context.Handler.GetType().ToString().Equals("Handler I want to enable session state for")))
{
//enable session state
app.Context.SetSessionStateBehavior(SessionStateBehavior.Required);
}
}
}
Another solution could be to route all request through your handler that requires session state and then pass those requests to internal handler by invoking its ProcessRequest method - you can create the instance of internal handler by using say Reflection (or using handler factory if any).
However, using HttpModule to swap handlers is definitely a better solution. Because you can choose to swap the handler selectively by looking at the requested URL. That way, you may not have to load/save session state for all requests (that can be expensive operation for out-of-proc sessions)

How to save data between calls to a IHttpHandler?

I have a IHttpHandler that acts as a source to a jQuery Autocomplete input field. In the constructor of the handler I generate an index that remains fairly static between request (needs to be rebuilt maybe once a day).
How can I cache the the index between calls? Debugging indicates that the constructor is called for each request. I've set IsReusable to "false".
Your handler is passed an HttpContext which means it has access to the application cache (e.g. context.Cache["Foo"] = myVal) and can save values there. However, you can also save the value in Session (e.g. context.Session["Bar"]) if your handler implements the IRequiresSessionState interface.
HttpHandlers have a special propert IsReusable. You can override that property in your Handler implementation and set it to return True. IsReusable is a value indicating whether another request can use the IHttpHandler instance.
So first time when the handler is accessed the Handler instance is created and upon next request the same instance serves the request back - so your caching trick will work right in this case.
http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.isreusable.aspx

Readonly access to session in a web service call?

We have a .net asmx web service that gets called from javascript (using ASP.Net AJAX), and requires access to Session.
[WebMethod(true)]
public string DoSomethingOnTheServer() { }
We're running into the problem of session being locked on a read/write request. Is there any way to mark a web service method as requiring read-only access to Session?
Thanks!
This is a really old thread, but i stumbled on it in my search for an answer to the same question.
I found the answer else where, and will leave it here for other internets in my place:
In Global.asax you can specify for each request, what access the request should have to the session object, and thereby if it should block or not.
private void Application_BeginRequest(object sender, EventArgs e)
{
// This will set the session to read only for asmx services
// This will make the asmx services non blocking for other requests as it doesnt lock the session object
if (Context.Request.Path.Contains(".asmx/"))
{
Context.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);
}
}
This way asmx services always only have read only access to the session and will not block other requests
This http://msdn.microsoft.com/en-us/library/aa480509.aspx page seems to suggest that the answer is "no" - you cannot mark a WebSerivce as having EnableSessionState=ReadOnly.
If you are making simultaneous Web service calls from the same process, the requests will be serialized at the server so that only one will execute at any one time. Unlike .ASPX pages that have support for read-only access to the HttpSessionState object, which allows for simultaneous processing of multiple requests, there is no such capability with ASP.NET Web services. All Web method calls with sessions enabled have read/write access and will be serialized within each session.
Warning: That article is old (2002).
According to the MSDN documentation of the WebMethod Attribute there are several possible properties, so I'm not sure what the 'true' value in your WebMethod Attribute going to do.
Have you tried:
[WebMethod(EnableSession=true)]
According to this document that should give you full access to the session.

How to provide a Session/Host object for use in both a windows and web application?

I have a web application that makes heavy use of the Session state to store information about the current user, their personal settings, record their session history and so on.
I have found myself retrieving this session information in my business layer, like so:
((UserSession)HttpContext.Current.Session["UserSession"]).User.Info
This poses a problem - at some point in the future my application will have a Windows client which obviously cannot reference the web Session state. So I need a host or customized session class that I can reference in my business layer that is agnostic of whether the application is running on the web or desktop. Something like:
IHost.User.Info
Behind the scenes, the web implementation will obviously utilize the Session state to store information, but I need to hide this away from my business layer. Has anyone solved this problem or got any practival advice on how best to approach this?
Help appreciated.
Assuming that the business layer is a separate DLL, I would never add a reference to System.Web and in consequence I would never use the Session object directly. This would lead to a different design of the business layer and of the exposed interfaces to a client (either web or winforms).
That said, as a quick workaround I would suggest to write a wrapper class in your business layer that hides the Session object from your code. Your calls from code will be something like this:
((UserSession) DualContext.Current["UserSession"]).User.Info
and the wrapper implementation will be something like this (not completed and tested):
public class DualContext
{
private Dictionary<string, object> winFormsSession = new Dictionary<string, object>();
private static readonly DualContext instance = new DualContext();
public static DualContext Current
{
get { return instance; }
}
public object this[string key]
{
get
{
if (HttpContext.Current != null)
return HttpContext.Current.Session[key];
else
return winFormsSession[key];
}
set
{
if (HttpContext.Current != null)
HttpContext.Current.Session[key] = value;
else
winFormsSession[key] = value;
}
}
}
It would take some re-architecting, but if you switch from using Session State to User Profiles you could then use Client Application Services to share the information.
http://msdn.microsoft.com/en-us/library/bb384297.aspx
I guess you need to create a webservice or RESTfull service. The service will return an XML file representing your user information. You will be able to invoke the service wither from you windows or web application.

Resources