亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

[水煮 ASP.NET Web API2 方法論](1-8)添加 Session 狀態

發布時間:2020-08-01 11:53:02 來源:網絡 閱讀:538 作者:水煮code 欄目:編程語言

問題

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 靜態類中使用 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 中使用 SessionASP.NET 將會顯示的為每一個實現了這個接口路由啟用 Session

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

 

代碼演示

繼承兩個類:

  • HttpControllerHandler

  • HttpControllerRouteHandler

我們將創建兩個自定義類

  • 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 類,因為我們需要執行 RouteCollection。接下來,我們應該在創建路由的時候,將 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 }
    );
}

 

 

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

當我們通過 Web API 的配置注冊路由的時候,路由是被注冊在 RouteTable 中,同時,使用一個單利 HttpControllerRouteHandler.Instance 處理器來處理路由。這樣,我們可以讓 ASP.NET 所有調用轉到Web API 路由,進入到 Web API 的管道。這里說到的單例其實就是一個 Lazy<HttpControllerRputeHandler>。我們可以在應用程序啟動的地方使用自己的類似 SessionHttpControllerRouteHandler 的類實例,然后繼續注冊路由到 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<HttpControllerRouteHandler>(() => 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 CTOhttp://shuizhucode.blog.51cto.com/


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

思南县| 务川| 嘉定区| 通海县| 鹤庆县| 曲阜市| 榆林市| 泗洪县| 旅游| 禹州市| 平遥县| 云梦县| 青铜峡市| 新安县| 南部县| 沿河| 朝阳县| 孝昌县| 花垣县| 开远市| 绥江县| 墨脱县| 理塘县| 蒙山县| 滨州市| 铜陵市| 美姑县| 闽侯县| 商都县| 斗六市| 喜德县| 新巴尔虎右旗| 蓝山县| 高密市| 诸城市| 建昌县| 资阳市| 榆社县| 博罗县| 弥渡县| 武强县|