在ASP.Net MVC中禁用每个请求的会话状态
我正在ASP.NETMVC中创建一个ActionResult来提供图像服务。启用会话状态后,IIS一次只能处理来自同一用户的一个请求。(这不仅适用于MVC。) 因此,在有多个图像调用此操作的页面上,一次只能处理一个图像请求。它是同步的 我希望这个映像操作是异步的——我希望每个映像都执行多个映像请求,而不需要前一个映像请求来完成。(如果图像只是静态文件,IIS将以这种方式提供它们。)在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是如何做到这一点的吗?谢谢 尝试
所以,我只想为对该操作的调用禁用会话,或者指定某些请求没有会话状态。有人知道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)]
参考:
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永远无法获得会话,因此没有必要。