最近在改寫WebApp時要將以前用泛型處理例程寫的Captcha 改成使用WebApi 來實作機制,在實作的過程中發現使用IRequiresSessionState session也無法使用(context.Session==null)
查過一些文章才發現需要在注冊api路由需將RouteHandler 改寫,才能使用。以下用
ASP.net MVC 4來說明要實作的部分
建立HttpControllerHandler和HttpControllerRouteHandler 並覆寫它
public class SessionRouteHandler : HttpControllerHandler, IRequiresSessionState { public SessionRouteHandler(RouteData routeData) : base(routeData) { } } public class SessionControllerRouteHandler : HttpControllerRouteHandler { protected override IHttpHandler GetHttpHandler(RequestContext requestContext) { return new SessionRouteHandler(requestContext.RouteData); } }
在WebApiConfig中將config.Routes.MapHttpRoute 改成
RouteTable.Routes.MapHttpRoute(using System.Web.Routing)並指定RouteHandler
public static void Register(HttpConfiguration config) { RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ).RouteHandler=new SessionControllerRouteHandler(); }
或者 在MVC的WebApi中默認是沒有開啟Session會話支持的。需要在
Global中重寫Init方法來指定會話需要支持的類型
public override void Init() { PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest; base.Init(); } void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) { HttpContext.Current.SetSessionStateBehavior( SessionStateBehavior.Required); }
或者:
public override void Init() { this.PostAuthenticateRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); base.Init(); }
在默認情況下是沒有開啟的。SessionStateBehavior有四個值:
Default使用默認ASP.NET邏輯來確定請求的會話狀態行為。默認邏輯是尋找IHttpHandler中是否存在標記會話狀態接口。
Disabled未啟用會話狀態來處理請求。 此設置將覆蓋已通過檢查請求的處理程序確定的任何會話行為。
ReadOnly為請求啟用只讀會話狀態。這意味着會話狀態無法更新。此設置將覆蓋已通過檢查請求的處理程序確定的任何會話狀態行為。
Required為請求啟用完全的讀寫會話狀態行為。 此設置將覆蓋已通過檢查請求的處理程序確定的任何會話行為。