真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯網站制作重慶分公司

[水煮ASP.NETWebAPI2方法論](1-8)添加Session狀態(tài)

問題

專注于為中小企業(yè)提供成都網站制作、做網站服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)隆化免費做網站提供優(yōu)質的服務。我們立足成都,凝聚了一批互聯網行業(yè)人才,有力地推動了上千多家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網站建設實現規(guī)模擴充和轉變。

ASP.NET Web API構建 Web應用程序時,要求使用 Session在服務器存儲一些用戶特定的信息

解決方案

ASP.NET Web API不支持 Session,因為 API根本不依賴于System.Web。他想試圖擺脫偽造 Session,非 HTTP這樣的概念。

然而,如果我們在 ASP.NET運行時中運行 ASP.NET Web API,還想啟用Session。我們可以通過兩種方式來做:

  • 全局:應用于整個API

  • 局部:應用于指定路由

啟用全局方式,我們需要在  Global.asax中通過SesssionStateBehavior.Required顯示的設置啟用Session行為。

 

protected void Application_PostAuthorizeRequest()
{
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}

 

 

啟用指定路由(局部方式),我們可以通過過使用路由處理器,讓路由處理器繼承自IRequiresSessionState。然后,我們可以在指定的路由上附加處理器,這個就在請求指定路由的時候啟用了 Session。

 

工作原理

默認的 ASP.NET Web API模板,會幫我們在WebApiConfig靜態(tài)類中使用 HttpConfiguration定義默認路由,因為,框架附帶的擴展方法是支持我們使用 System.Web.RouteCollection,在定義 MVC路由的地方定義 Web API路由。

雖然 MapHttpRoute的多個重載方法經常被使用,但是這些重載方法都是void(無返回值)方法,實際上,方法還是返回了一個最新聲明路由的實例,只是方法的調用結果一般都是被拋棄掉的。在使用 Syste.Web.RouteCollection直接定義路由的情況下,返回值是 System.Web.Route的對象,我們可以將其賦值給 IrouteHandler。

當運行在 ASP.NET的時候,ASP.NET Web API框架使用同樣的機制來確保 Api請求可以準確到達,他會賦值 HttpControllerRouteHandler給每一個 Web API路由,HttpControllerRouteHandler是 GetHttpHandler方法返回的一個HttpControllerHandler實例,這是 ASP.NET Web API管道的入口點。HttpControllerHandler(WEB API的核心)雖然很復雜,但是究其原理也就是一個傳統的 IHttpAsyncHandler(舊的 IHttpHandler的一個異步的版本)。

我們可以通過實現IRequiresSessionState的接口,來強制在 IHttpHandler中使用 Session。ASP.NET將會顯示的為每一個實現了這個接口路由啟用 Session。

另外要在全局范圍內調用 HttpContext.Current.SetSessionStateBehavior方法和傳遞 SessionStateBehavior,需要為當前的HttpContext顯示的啟用 Session。SetSessionStateBehavior方法必須在 AcquireRequestState事件之前調用。

 

代碼演示

繼承兩個類:

  • HttpControllerHandler

  • HttpControllerRouteHandler

我們將創(chuàng)建兩個自定義類

  • SessionHttpControllerHandler:實現     IRequiresSessionState

  • SessionHttpControllerRouteHandler:只是代替默認類型,來充當返回     SessionHttpControllerHandler的工廠

如清單 1-26所示。

 

清單 1-26.定制HttpControllerHandler和 HttpControllerRouteHandler

 

public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState
{
    public SessionControllerHandler(RouteData routeData)
        : base(routeData)
    { }
}
public class SessionHttpControllerRouteHandler : HttpControllerRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new SessionControllerHandler(requestContext.RouteData);
    }
}

 

 

現在我們需要將我們的注意力從WebApiConfig類轉移到 RouteConfig類,因為我們需要執(zhí)行 RouteCollection。接下來,我們應該在創(chuàng)建路由的時候,將 SessionHttpControllerRouteHandler賦值給 RouteHandler。如清單 1-27所示。

 

清單 1-27. 在System.Web.RouteCollection中注冊Web API路由

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    //Web API
    routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
    ).RouteHandler = new SessionHttpControllerRouteHandler();
    //MVC
    routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

 

 

如果想激進一點,還是有其他的方式來執(zhí)行這個功能的。不再需要跑到RouteConfig中注冊 Api的路由,而是需要使用 WebApiConfig中的 HttpConfiguration做一些必要的處理,可以同樣達對所有  Web API路由啟用 Session。

當我們通過Web API的配置注冊路由的時候,路由是被注冊在 RouteTable中,同時,使用一個單利 HttpControllerRouteHandler.Instance處理器來處理路由。這樣,我們可以讓 ASP.NET所有調用轉到Web API路由,進入到 Web API的管道。這里說到的單例其實就是一個 Lazy。我們可以在應用程序啟動的地方使用自己的類似 SessionHttpControllerRouteHandler的類實例,然后繼續(xù)注冊路由到 HttpConfiguration,同時,這樣可以確保每一個 Web API路由都使用了SessionHttpControllerRouteHandler,也就是說所有的路由都可以訪問Session。這個簡單的代碼如清單 1-28所示。

清單 1-28. 配置 Session

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var httpControllerRouteHandler = typeof(HttpControllerRouteHandler).GetField("_instance",
        BindingFlags.Static | BindingFlags.NonPublic);
        if (httpControllerRouteHandler != null)
        {
            httpControllerRouteHandler.SetValue(null,
            new Lazy(() => new SessionHttpControllerRouteHandler(),
            true));
        }
        config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
        );
        config.MapHttpAttributeRoutes();
    }
}

 

現在,我們需要證明這個起作用了,需要做一個簡單模擬擲骰子的ApiController例子。首先,生成一個 1到 6之間的隨機數,將 Session中上一次的值使用當前投擲的值賦值。

 

清單 1-29.使用Session的 ApiController簡單例子

public class DiceResult
{
    public int NewValue { get; set; }
    public int LastValue { get; set; }
}
public class DiceController : ApiController
{
    public DiceResult Get()
    {
        var newValue = new Random().Next(1, 7);
        object context;
        if (Request.Properties.TryGetValue("MS_HttpContext", out context))
        {
            var httpContext = context as HttpContextBase;
            if (httpContext != null && httpContext.Session != null)
            {
                var lastValue = httpContext.Session["LastValue"] as int?;
                httpContext.Session["LastValue"] = newValue;
                return new DiceResult
                {
                    NewValue = newValue,
                    LastValue = lastValue ?? 0
                };
            }
        }
        return new DiceResult { NewValue = newValue };
    }
}

 

值得注意的是,我們剛剛獲取的HttpContext是從 HttpRequestMessage屬性字典中通過“MS_HttpContextkey”獲取的。這個比直接從System.HttpContext.Current中獲取更具可測性。

 

博客園:http://www.cnblogs.com/shuizhucode/

51 CTO:http://shuizhucode.blog.51cto.com/


網頁標題:[水煮ASP.NETWebAPI2方法論](1-8)添加Session狀態(tài)
分享地址:http://weahome.cn/article/gojdoi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部