在ASP.Net MVC中禁用会话状态每个请求
我正在ASP.Net MVC中创build一个ActionResult服务图像。 在启用会话状态的情况下,IIS一次只能从同一个用户处理一个请求。 (这不仅仅是在MVC中)
因此,在具有多个调用此Action的图像的页面上,一次只能处理一个图像请求。 这是同步的。
我想这个图像的行动是asynchronous的 – 我想多个图像请求,每个执行,而不需要以前完成。 (如果图像只是静态文件,IIS将以这种方式提供服务。)
所以,我想禁用会话只是为了调用该动作,或者指定某些请求没有会话状态。 任何人都知道这是如何在MVC中完成? 谢谢!
为什么不实现一个RouteHandler
呢,而不是实现一个动作filter呢?
这是交易 – IRouteHandler
有一个方法 – GetHttpHandler
。 当您向控制器发出ASP.Net MVC请求时,默认情况下,路由引擎通过创build一个MvcRouteHandler
的新实例来处理请求,该实例返回一个MvcHandler
。 MvcHandler
是IHttpHandler
一个实现,它标有(surprise!) IRequiresSessionState
接口。 这就是为什么一个普通的请求使用会话。
如果您按照我的博客文章 ,了解如何实现自定义RouteHandler
(而不是使用MvcRouteHandler)来提供图像,则可以跳过返回会话标记的IHttpHandler
。
这应该使IIS免受同步性的影响。 这也可能是更高性能的,因为它跳过处理filter的MVC代码的所有层。
如果有人处于我处于的状态,您的映像控制器实际上只需要访问会话,则可以将SessionState属性放在控制器上
[SessionState(SessionStateBehavior.ReadOnly)]
有关更多信息,请参阅http://msdn.microsoft.com/zh-CN/library/system.web.mvc.sessionstateattribute.aspx 。
尝试提供来自其他网域的图片。 所以像像.mysite.com。
这将为您提供两个好处:一,会话由一个cookie跟踪,所以images.mysite.com将不会有cookie。 二,它会给你额外的两个并发请求来检索图像。
你有没有考虑设置一个HttpHandler来提供你的图像?
SessionState属性是相当有用的,如果你使用mvc3。 如何用mvc2实现这一点需要多一点编码。
想法是告诉asp.net具体的请求不会使用会话对象。
所以,为特定请求创build一个自定义路由处理程序
public class CustomRouteHandler : IRouteHandler { public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext) { requestContext.HttpContext.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly); return new MvcHandler(requestContext); } }
SessionStateBehavior枚举有4个成员,您应该使用“禁用”或“只读”模式来获得asynchronous行为。
创build此自定义路由处理程序后,请确保您的特定请求通过此处理程序。 这可以通过在Global.asax中定义新的路由来完成
routes.Add("Default", new Route( "{controller}/{action}", new RouteValueDictionary(new { controller = "Home", action = "Index"}), new CustomRouteHandler() ));
添加此路由使得您的所有请求都由您的自定义路由处理程序类来处理。 您可以通过定义不同的路线来使其具体化。
将DefaultCOntrollerFactory更改为自定义ControllerFactory类。 默认的Controller.TempDataProvider使用SessionStateTempDataProvider。 你可以改变它。
1.设置web.config / system.web / sessionState:mode =“Off”。
2.创buildDictionaryTempDataProvider类。
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.创buildDictionaryTempDataControllerFactory
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.在global.asax.cs Apprication_Start事件集中DictionaryTempDataControllerFactory。
protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory( new DictionaryTempDataControllerFactory() ); }
我也遇到了同样的问题,并做了研发后,这个链接为我工作参考: https : //technologyatfingertips.wordpress.com/2016/06/14/session-state-on-action/
- 创build自定义属性
- 覆盖DefaultControllerFactory类中的“GetControllerSessionBehavior”方法。
- 在global.aspx注册
1> 创build自定义属性
public sealed class ActionSessionStateAttribute : Attribute { public SessionStateBehavior SessionBehavior { get; private set; } public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior) { SessionBehavior = sessioBehavior; } }
2.覆盖
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.在Global.asax中注册类
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { // --- other code --- ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory)); } }
在我们的服务器上,IIS甚至不知道会话 – 一次处理一个会话的ASP.NET堆栈。 静态文件,如图像,从不受影响。
有没有可能你的ASP.NET应用程序提供的文件,而不是IIS?
创build新的控制器
用[SessionState(SessionStateBehavior.Disabled)]装饰控制器
您希望seeion的重构代码被禁用到该控制器