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.
wom*_*omp 36
不是为此实现动作过滤器,为什么不实现RouteHandler?
这是交易 - IRouteHandler有一种方法 - GetHttpHandler.当您向控制器发出ASP.Net MVC请求时,默认情况下,路由引擎通过创建一个新实例来处理请求,该实例MvcRouteHandler返回一个MvcHandler. MvcHandler是一个IHttpHandler用(surprise!)IRequiresSessionState接口标记的实现.这就是普通请求使用Session的原因.
如果您关注我的博客文章如何实现自定义RouteHandler(而不是使用MvcRouteHandler)来提供图像 - 您可以跳过返回会话标记IHttpHandler.
这应该可以让IIS免于同步.它也可能更具性能,因为它正在跳过处理过滤器的MVC代码的所有层.
我也遇到了同样的问题,经过研发后,这个链接对我有用参考:https: //techatfingers.wordpress.com/2016/06/14/session-state-on-action/
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)
尝试提供来自其他域的图像.像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)
添加此路由会使您的所有请求都由您的自定义路由处理程序类处理。您可以通过定义不同的路线来使其具体化。
| 归档时间: |
|
| 查看次数: |
27683 次 |
| 最近记录: |