Disable Session state per-request in ASP.Net MVC
If anyone is in the situation I was in, where your image controller actually needs read only access to the session, you can put the SessionState attribute on your controller
[SessionState(SessionStateBehavior.ReadOnly)]
See http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx for more info.
Rather than implementing an action filter for this, why don't you implement a RouteHandler
?
Here's the deal - IRouteHandler
has one method - GetHttpHandler
. When you make an ASP.Net MVC request to a controller, by default the routing engine handles the request by creating a new instance of MvcRouteHandler
, which returns an MvcHandler
. MvcHandler
is an implementation of IHttpHandler
which is marked with the (surprise!) IRequiresSessionState
interface. This is why a normal request uses Session.
If you follow my blog post on how to implement a custom RouteHandler
(instead of using MvcRouteHandler) for serving up images - you can skip returning a session-tagged IHttpHandler
.
This should free IIS from imposing synchronicity on you. It would also likely be more performant because it's skipping all the layers of the MVC code dealing with filters.
I also came across the same problem and after doing R&D this link worked for meReference: https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/
- Create custom Attribute
- Override the “GetControllerSessionBehavior” method present in class DefaultControllerFactory.
- Register it in global.aspx
1> Create custom Attribute
public sealed class ActionSessionStateAttribute : Attribute { public SessionStateBehavior SessionBehavior { get; private set; } public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior) { SessionBehavior = sessioBehavior; } }
2. Override
public class SessionControllerFactory : DefaultControllerFactory{ protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType) { if (controllerType == null) return SessionStateBehavior.Default; var actionName = requestContext.RouteData.Values["action"].ToString(); Type typeOfRequest=requestContext.HttpContext.Request.RequestType.ToLower() =="get"?typeof(HttpGetAttribute):typeof(HttpPostAttribute); // [Line1] var cntMethods = controllerType.GetMethods() .Where(m => m.Name == actionName && ( ( typeOfRequest == typeof(HttpPostAttribute) && m.CustomAttributes.Where(a => a.AttributeType == typeOfRequest).Count()>0 ) || ( typeOfRequest == typeof(HttpGetAttribute) && m.CustomAttributes.Where(a => a.AttributeType == typeof(HttpPostAttribute)).Count() == 0 ) ) ); MethodInfo actionMethodInfo = actionMethodInfo = cntMethods != null && cntMethods.Count() == 1 ? cntMethods.ElementAt(0):null; if (actionMethodInfo != null) { var sessionStateAttr = actionMethodInfo.GetCustomAttributes(typeof(ActionSessionStateAttribute), false) .OfType<ActionSessionStateAttribute>() .FirstOrDefault(); if (sessionStateAttr != null) { return sessionStateAttr.Behavior; } } return base.GetControllerSessionBehavior(requestContext, controllerType); }
3. Register class in Global.asax
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { // --- other code --- ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory)); }}