請記住,使用SessionStateBehavior.Required會產生相當大的影響,只有部分路由實際上需要對會話進行寫入訪問。最糟糕的情況是每個用戶只能處理一個請求,因爲會話必須被鎖定。
這就是說,有一種方法可以根據路線以不同的方式處理會話。
您可以使用IHttpRoute.DataTokens爲您的路線添加自定義字段。 我創建了一個小的擴展類設置SessionStateBehavior爲每個路由,分別:
public static class SessionHelper
{
private static SessionStateBehavior GetSessionStateBehavior(IDictionary<string, object> dataTokens)
{
return dataTokens.ContainsKey("SessionStateBehavior") ? (SessionStateBehavior)dataTokens["SessionStateBehavior"] : SessionStateBehavior.Default;
}
public static SessionStateBehavior GetSessionStateBehavior(this IHttpRoute route)
{
return GetSessionStateBehavior(route.DataTokens);
}
public static SessionStateBehavior GetSessionStateBehavior(this RouteData routeData)
{
return GetSessionStateBehavior(routeData.DataTokens);
}
public static void SetSessionStateBehavior(this IHttpRoute route, SessionStateBehavior behavior)
{
route.DataTokens["SessionStateBehavior"] = behavior;
}
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, SessionStateBehavior behavior)
{
return MapHttpRoute(routes, name, routeTemplate, defaults, null, behavior);
}
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, SessionStateBehavior behavior)
{
var route = routes.CreateRoute(routeTemplate, defaults, constraints);
SetSessionStateBehavior(route, behavior);
routes.Add(name, route);
return route;
}
}
當設置你的路線,你可以使用擴展定義一個特定的會話狀態行爲:
config.Routes.MapHttpRoute(
"DefaultSessionApi",
"api/{controller}/{id}",
new { id = RouteParameter.Optional },
SessionStateBehavior.ReadOnly);
config.Routes.MapHttpRoute(
"WriteStuffToSession",
"api/writestufftosession",
null,
SessionStateBehavior.Required);
然後,在PostAuthorizeRequest事件中,可以解析您的路由並相應地設置SessionStateBehavior:
protected void Application_PostAuthorizeRequest()
{
var context = new HttpContextWrapper(HttpContext.Current);
var path = context.Request.AppRelativeCurrentExecutionFilePath;
if (path == null || !path.StartsWith("~/api"))
{
return;
}
var routeData = RouteTable.Routes.GetRouteData(context);
if (routeData != null)
{
context.SetSessionStateBehavior(routeData.GetSessionStateBehavior());
}
}
我不在Mono中工作。 – Andrus 2016-08-15 19:39:31