在ASP.Net MVC中禁用每个请求的会话状态

Mat*_*man 46 asp.net asp.net-mvc asynchronous session-state actionresult

我在ASP.Net MVC中创建一个ActionResult来提供图像.启用会话状态后,IIS将一次只处理来自同一用户的一个请求.(这不仅适用于MVC.)

因此,在具有多个图像回调此Action的页面上,一次只能处理一个图像请求.这是同步的.

我希望这个图像Action是异步的 - 我希望每次执行多个图像请求而不需要前一个完成.(如果图像只是静态文件,IIS会以这种方式为它们提供服务.)

所以,我想禁用Session仅用于对该Action的调用,或者指定某些请求没有Session状态.任何人都知道如何在MVC中完成这项工作?谢谢!

Sam*_*ens 55

如果有人遇到我所处的情况,你的图像控制器实际上只需要只读访问会话,你可以将SessionState属性放在你的控制器上

[SessionState(SessionStateBehavior.ReadOnly)]
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx.

感谢/sf/answers/296450451/


wom*_*omp 36

不是为此实现动作过滤器,为什么不实现RouteHandler

这是交易 - IRouteHandler有一种方法 - GetHttpHandler.当您向控制器发出ASP.Net MVC请求时,默认情况下,路由引擎通过创建一个新实例来处理请求,该实例MvcRouteHandler返回一个MvcHandler. MvcHandler是一个IHttpHandler用(surprise!)IRequiresSessionState接口标记的实现.这就是普通请求使用Session的原因.

如果您关注我的博客文章如何实现自定义RouteHandler(而不是使用MvcRouteHandler)来提供图像 - 您可以跳过返回会话标记IHttpHandler.

这应该可以让IIS免于同步.它也可能更具性能,因为它正在跳过处理过滤器的MVC代码的所有层.

  • 值得了解:http://www.c-sharpcorner.com/UploadFile/ff2f08/session-state-behavior-per-action-in-Asp-Net-mvc/ (3认同)

See*_*heC 8

我也遇到了同样的问题,经过研发后,这个链接对我有用参考:https: //techatfingers.wordpress.com/2016/06/14/session-state-on-action/

  1. 创建自定义属性
  2. 覆盖类DefaultControllerFactory中的"GetControllerSessionBehavior"方法.
  3. 在global.aspx中注册

1> 创建自定义属性

public sealed class ActionSessionStateAttribute : Attribute
    {
            public SessionStateBehavior SessionBehavior { get; private set; }          
            public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
            {
                SessionBehavior = sessioBehavior;
            }
    }
Run Code Online (Sandbox Code Playgroud)

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);
 }
Run Code Online (Sandbox Code Playgroud)

3.在Global.asax中注册类

public class MvcApplication : System.Web.HttpApplication
 {
        protected void Application_Start()
        {
            // --- other code ---
            ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory));
        }
}
Run Code Online (Sandbox Code Playgroud)


Chu*_*way 6

尝试提供来自其他域的图像.像images.mysite.com这样的东西.

这将为您提供两个好处:一,会话由cookie跟踪,因此images.mysite.com将没有cookie.第二,它将为您提供额外的两个并发请求来检索图像.

您是否考虑过设置HttpHandler来提供图片?


小智 5

如果您使用mvc3,则SessionState属性非常有用。如何使用mvc2实现这一点需要更多的编码。

想法是告诉asp.net特定请求将不使用会话对象。

因此,为特定请求创建自定义路由处理程序

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

SessionStateBehavior枚举有4个成员,您应该使用“禁用”或“只读”模式来获取异步行为。

创建此自定义路由处理程序后,请确保您的特定请求通过此处理程序。这可以通过在Global.asax上定义新路线来完成

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

添加此路由会使您的所有请求都由您的自定义路由处理程序类处理。您可以通过定义不同的路线来使其具体化。