[ACCEPTED]-Disable Session state per-request in ASP.Net MVC-actionresult

Accepted answer
Score: 57

If anyone is in the situation I was in, where 4 your image controller actually needs read 3 only access to the session, you can put 2 the SessionState attribute on your controller

[SessionState(SessionStateBehavior.ReadOnly)]

See 1 http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx for more info.

Thanks to https://stackoverflow.com/a/4235006/372926

Score: 37

Rather than implementing an action filter 15 for this, why don't you implement a RouteHandler?

Here's 14 the deal - IRouteHandler has one method - GetHttpHandler. When you 13 make an ASP.Net MVC request to a controller, by 12 default the routing engine handles the request 11 by creating a new instance of MvcRouteHandler, which returns 10 an MvcHandler. MvcHandler is an implementation of IHttpHandler which is 9 marked with the (surprise!) IRequiresSessionState interface. This 8 is why a normal request uses Session.

If 7 you follow my blog post on how to implement a custom RouteHandler (instead 6 of using MvcRouteHandler) for serving up 5 images - you can skip returning a session-tagged 4 IHttpHandler.

This should free IIS from imposing synchronicity 3 on you. It would also likely be more performant 2 because it's skipping all the layers of 1 the MVC code dealing with filters.

Score: 9

I also came across the same problem and 2 after doing R&D this link worked for 1 me Reference: https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/

  1. Create custom Attribute
  2. Override the “GetControllerSessionBehavior” method present in class DefaultControllerFactory.
  3. 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));
        }
}
Score: 7

Try serving the images from another domain. So 8 something like images.mysite.com.

This will 7 provide you two benefits: One, sessions 6 are tracked by a cookie, so images.mysite.com 5 won't have the cookie. Two, it will give 4 you an additional two concurrent requests 3 to retrieve images.

Have you considered 2 setting up a HttpHandler to serve up your 1 images?

Score: 5

SessionState attribute is quite helpful 14 if u use mvc3. How to achieve this with 13 mvc2 needs a little more coding.

Idea is 12 to tell the asp.net that specific request 11 wont use session object.

So, Create a custom 10 route handler for specific requests

public class CustomRouteHandler : IRouteHandler
    {
        public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.HttpContext.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
            return new MvcHandler(requestContext);
        }
    }

SessionStateBehavior 9 enum has 4 members, you should use "disabled" or 8 "readonly" modes to get async behavior.

After 7 creating this custom route handler, be sure 6 that your specific requests goes through 5 this handler. This can be done via defining 4 new routes at Global.asax

routes.Add("Default", new Route(
                "{controller}/{action}",
               new RouteValueDictionary(new { controller = "Home", action = "Index"}),
               new CustomRouteHandler()
                ));

Adding this route 3 makes all your requests to be handled by 2 your custom route handler class. You can 1 make it specific by defining different routes.

Score: 3

Change DefaultCOntrollerFactory to custom 7 ControllerFactory class. Default Controller.TempDataProvider 6 use SessionStateTempDataProvider. you can 5 change it.

1.Set web.config/system.web/sessionState:mode="Off".

2.create 4 DictionaryTempDataProvider class.

  public class DictionaryTempDataProvider : ITempDataProvider
  {
    public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
    {
      return new Dictionary<string, object>();
    }

    public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
    {
    }
  }

3.Create 3 DictionaryTempDataControllerFactory

  public class DictionaryTempDataControllerFactory : DefaultControllerFactory
  {
    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
      var controller = base.CreateController(requestContext, controllerName) as Controller;
      if (controller!=null)
        controller.TempDataProvider = new DictionaryTempDataProvider();

      return controller;
    }
  }

4.In 2 global.asax.cs Apprication_Start event set 1 DictionaryTempDataControllerFactory.

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);

  ControllerBuilder.Current.SetControllerFactory(
   new DictionaryTempDataControllerFactory()
  );
}
Score: 1

On our server, IIS doesn't even know about 5 sessions - it's the ASP.NET stack that handles 4 one request per session at a time. Static 3 files, like images, are never affected.

Is 2 it possible that your ASP.NET app is serving 1 the files instead of IIS?

Score: 1

Create new Controller

Decorate controler 3 with [SessionState(SessionStateBehavior.Disabled)]

Refactor 2 code you want seesion stated disabled for 1 to that controller

Score: 0

I would to share my solution for disable 2 ASP.NET Session for an specific request 1 (in my case, a WCF Service) using an HttpModule:

public class AspNetSessionFilterModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostMapRequestHandler += OnPostMapRequestHandler;
    }

    private void OnPostMapRequestHandler(object sender, EventArgs e)
    {
        var context = (sender as HttpApplication).Context;
        DisableSessionForSomeRequests(context);
    }

    private void DisableSessionForSomeRequests(HttpContext context)
    {
        if ("~/Services/MyService.svc".Equals(context.Request.AppRelativeCurrentExecutionFilePath, StringComparison.InvariantCultureIgnoreCase))
        {
            context.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Disabled);
        }
    }

    public void Dispose()
    { }
}

More Related questions