Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ASP.Net MVC中禁用每个请求的会话状态_Asp.net_Asp.net Mvc_Asynchronous_Session State_Actionresult - Fatal编程技术网

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

在ASP.Net MVC中禁用每个请求的会话状态,asp.net,asp.net-mvc,asynchronous,session-state,actionresult,Asp.net,Asp.net Mvc,Asynchronous,Session State,Actionresult,我正在ASP.NETMVC中创建一个ActionResult来提供图像服务。启用会话状态后,IIS一次只能处理来自同一用户的一个请求。(这不仅适用于MVC。) 因此,在有多个图像调用此操作的页面上,一次只能处理一个图像请求。它是同步的 我希望这个映像操作是异步的——我希望每个映像都执行多个映像请求,而不需要前一个映像请求来完成。(如果图像只是静态文件,IIS将以这种方式提供它们。) 所以,我只想为对该操作的调用禁用会话,或者指定某些请求没有会话状态。有人知道MVC是如何做到这一点的吗?谢谢 尝试

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

因此,在有多个图像调用此操作的页面上,一次只能处理一个图像请求。它是同步的

我希望这个映像操作是异步的——我希望每个映像都执行多个映像请求,而不需要前一个映像请求来完成。(如果图像只是静态文件,IIS将以这种方式提供它们。)


所以,我只想为对该操作的调用禁用会话,或者指定某些请求没有会话状态。有人知道MVC是如何做到这一点的吗?谢谢

尝试为来自其他域的图像提供服务。比如images.mysite.com

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


您是否考虑过设置一个HttpHandler来为您的映像提供服务?

与其为此实现一个操作过滤器,不如实现一个
路由处理器

这里是交易-
irouthandler
有一个方法-
GetHttpHandler
。当您向控制器发出ASP.Net MVC请求时,默认情况下,路由引擎通过创建
MvcRouteHandler
的新实例来处理该请求,该实例返回一个
MvcHandler
MvcHandler
IHttpHandler
的一个实现,它用(惊奇!)
IRequiresessionState
接口标记。这就是正常请求使用会话的原因

如果您了解如何实现自定义
RouteHandler
(而不是使用MvcRouteHandler)来提供图像,您可以跳过返回标记为
IHttpHandler
的会话


这将使IIS免于对您施加同步性。它的性能也可能更高,因为它跳过了处理过滤器的MVC代码的所有层。

在我们的服务器上,IIS甚至不知道会话-是ASP.NET堆栈一次处理每个会话一个请求。静态文件,如图像,永远不会受到影响


是否有可能您的ASP.NET应用程序正在提供文件而不是IIS?

将DefaultCOntrollerFactory更改为custom ControllerFactory类。默认Controller.TempDataProvider使用SessionStateTempDataProvider。你可以改变它

1.设置web.config/system.web/sessionState:mode=“Off”

2.创建DictionaryTempDataProvider类

  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)
    {
    }
  }
4.在global.asax.cs Approvision\u启动事件集DictionaryTempDataControllerFactory中

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

  ControllerBuilder.Current.SetControllerFactory(
   new DictionaryTempDataControllerFactory()
  );
}

如果有人处于我所处的情况,您的图像控制器实际上需要对会话进行只读访问,那么您可以在控制器上设置SessionState属性

[SessionState(SessionStateBehavior.ReadOnly)]
有关更多信息,请参阅


由于

如果您使用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);
        }
    }
SessionStateBehavior枚举有4个成员,您应该使用“禁用”或“只读”模式来获取异步行为

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

routes.Add("Default", new Route(
                "{controller}/{action}",
               new RouteValueDictionary(new { controller = "Home", action = "Index"}),
               new CustomRouteHandler()
                ));
添加此路由将使您的所有请求都由自定义路由处理程序类处理。您可以通过定义不同的路由使其具体化。

创建新控制器

用[SessionState(SessionStateBehavior.Disabled)]装饰控件


重构您希望为该控制器禁用的代码

我也遇到了同样的问题,在做了研发之后,这个链接对我有效
[SessionState(SessionStateBehavior.ReadOnly)]
参考:

  • 创建自定义属性
  • 重写类DefaultControllerFactory中的“GetControllerSessionBehavior”方法
  • 在global.aspx中注册它
  • 1> 创建自定义属性

    public sealed class ActionSessionStateAttribute : Attribute
        {
                public SessionStateBehavior SessionBehavior { get; private set; }          
                public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
                {
                    SessionBehavior = sessioBehavior;
                }
        }
    
    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);
     }
    
    2。覆盖

    public sealed class ActionSessionStateAttribute : Attribute
        {
                public SessionStateBehavior SessionBehavior { get; private set; }          
                public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
                {
                    SessionBehavior = sessioBehavior;
                }
        }
    
    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);
     }
    

    这是一个有趣的想法。我可以全面禁用该应用程序/站点的会话状态。我仍然想知道每一个请求/每一个动作是否也可能。哇,很棒的博客文章。似乎使用标准的MVC控制器,会话依赖是不可避免的….?是的。幸运的是,他们使MVC尽可能具有可扩展性,所以绕过任何您不喜欢的内容不需要太多工作。谢谢!当我关闭会话并且返回图像的操作与结果(使用此操作的页面上的可能图像)混合时,这对我来说是一种痛苦。@rwalter您现在可以替换您的评论。将链接替换为一个存档的链接,值得一提的是:没错,执行会话/同步的是ASP,而不是IIS本身。解决方案是按照上面所述的womp提前进行。这是一个很好的特性,但是它只在MVC3+中起作用。您的解决方案是针对mvc 3+的,在您编写mvc 2时,您是否可以分享如何在mvc 2中实现这一点,只需稍微增加一些编码?以防它对任何人都有价值,这在mvc 5.2.3.0中仍然适用于我。然而,我不得不将
    会话状态行为更改为
    禁用
    ,并在
    RouteConfig.cs
    中添加路由(方法
    注册表项(RouteCollection)
    ),而不是在
    全局.asax
    中。如果您想为ApicController添加路由,该怎么办?ApicController永远无法获得会话,因此没有必要。