ASP.NET Web Api中使用Session、Cache和Application的几个方法
2015-08-31 15:29
417 查看
在ASP.NET中,Web Api的控制器类派生自ApiControll,该类与ASP.NET的Control类没有直接关系,因此不能像在ASPX.CS代码隐藏类中直接使用HttpContext、HttpApplicationState或HttpSessionState等状态数据。要使用的话,一般是从System.Web.HttpContext.Current静态对象引用HttpContext,从而使用Session等状态数据。
不过,要在控制器类中通过HttpContext的Session属性直接使用Session状态数据,将抛出null reference异常。网查主要有两个解决办法,一个是重载Global的Init()方法,在该方法的中开放Session状态,另一个设计带Session的路由处理器。
下面代码是包含两个解决方法的Global类。
为测试上述行为,编写了如下控制器代码。
下面是网页的代码隐藏类。
比较两个实现方法可以知道,使用带Session的路由处理器方法可以指定某个路由开放Session(比如上面的api/{controller}/{id}/{id2},就不能读取Session中的数据)。而使用Global的Init()方法中开放Session,将使得全部Api都可以访问Session。
不过,要在控制器类中通过HttpContext的Session属性直接使用Session状态数据,将抛出null reference异常。网查主要有两个解决办法,一个是重载Global的Init()方法,在该方法的中开放Session状态,另一个设计带Session的路由处理器。
下面代码是包含两个解决方法的Global类。
<pre name="code" class="csharp">using System; using System.Web; using System.Web.Routing; using System.Web.Http; using System.Web.Http.WebHost; using System.Web.SessionState; namespace ApiControllerExample { public class Global : System.Web.HttpApplication { public override void Init() { //this.PostAuthenticateRequest += (s, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); base.Init(); } protected void Application_Start(object sender, EventArgs e) { RouteConfig.RegisterRoutes(RouteTable.Routes); // 注册路由 } } public class SessionableControllerHandler : HttpControllerHandler, IRequiresSessionState { public SessionableControllerHandler(RouteData routeData) : base(routeData) { } } public class SessionStateRouteHandler : IRouteHandler { IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) { return new SessionableControllerHandler(requestContext.RouteData); } } public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.MapHttpRoute( name: "WebApiRoute1", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ).RouteHandler = new SessionStateRouteHandler(); // 使用Session routes.MapHttpRoute( name: "WebApiRoute2", routeTemplate: "api/{controller}/{id}/{id2}", defaults: new{id = RouteParameter.Optional } ); // 不使用Session } } }
为测试上述行为,编写了如下控制器代码。
using System; using System.Web.Http; namespace ApiControllerExample { public class StateController : ApiController { public string Get(int id) { try { return GetStateInfo(id); } catch (Exception err) { return "excep: " + err.Message; } } private string GetStateInfo(int id) { System.Web.HttpContext context = System.Web.HttpContext.Current; if (id == 1) { return context.Session["state"].ToString(); } else if (id == 2) { return context.Cache["state"].ToString(); } else { return context.Application["state"].ToString(); } } public string Get(int id, int id2) { System.Web.HttpContext context = System.Web.HttpContext.Current; try { return context.Session["state"].ToString(); } catch (Exception err) { return "excep: " + err.Message; } } } }下面是测试用的ASPX网页代码。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ApiControllerExample.Test" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script> function GetXmlHttpRequest() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } return null; } function GetState(id) { var request = GetXmlHttpRequest(); var url = "/api/state/" + id; request.open("GET", url, false); request.send(null); alert(request.responseText); } function GetState2() { var request = GetXmlHttpRequest(); var url = "/api/state/1/1"; request.open("GET", url, false); request.send(null); alert(request.responseText); } </script> </head> <body> <input type="button" value="GetSession" onclick="GetState(1)" /> <input type="button" value="GetCache" onclick="GetState(2)" /> <input type="button" value="GetAppication" onclick="GetState(3)" /> <input type="button" value="GetSession(state2)" onclick="GetState2()" /> </body> </html>
下面是网页的代码隐藏类。
using System; namespace ApiControllerExample { public partial class Test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string time = DateTime.Now.ToString(); Session["state"] = time; Cache["state"] = time; Application["state"] = time; } } }测试时,可以取消Global类中的有关注释即可。
比较两个实现方法可以知道,使用带Session的路由处理器方法可以指定某个路由开放Session(比如上面的api/{controller}/{id}/{id2},就不能读取Session中的数据)。而使用Global的Init()方法中开放Session,将使得全部Api都可以访问Session。
相关文章推荐
- Unity3D中使用MiniJson解析json的例子
- ios sdk的排查过程
- 按钮单击事件的四种写法(转)
- android 代码混淆 proguard
- Knockout应用开发指南 第七章:Mapping插件
- org.hibernate.hql.ast.QuerySyntaxException: is not mapped
- Android Gson解析JSON数据
- cocos2d-x 3.4版本游戏打包AKP (重点记录如何解决打包过程中遇到的各种问题)
- android 用 XML 自定义边框(只上下边框有色)
- IOS第15天(1,事件处理View的拖拽)
- Android中dp转换为px
- cocos2d-x 百分比动作2 Progress水平模式
- unity制作简单血条
- Android插件实例——360 DroidPlugin详解
- android audio截取PCM数据
- 深入浅出RxJava四-在Android中使用响应式编程
- Unity中的FPS的计算方式
- [应用代码] Android 动画特效大全
- cocos2dx 屏幕适配
- 用Android Studio 导出jar包