[ACCEPTED]-Disable Session state per-request in ASP.Net MVC-actionresult
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.
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.
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/
- 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));
}
}
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?
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.
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()
);
}
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?
Create new Controller
Decorate controler 3 with [SessionState(SessionStateBehavior.Disabled)]
Refactor 2 code you want seesion stated disabled for 1 to that controller
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.