webapi session
webapi中使用session 修改global.cs里面的内容 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() { //取下注释下面这行语句,将使得全部Api都可以访问Session //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 } } } webapi用例: 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(); } } //这个方法无法使用Session 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; } } } }
Web APi全局启动Session(一)
以下皆在Global.asax全局文件中进行。
第一步(定义两个变量)
private const string WebApiPrefix = "APi";
private static string WebApiExecutePath = string.Format("~/{0}", WebApiPrefix);
第二步(获取当前请求的路径)
private bool isWebAPiRequest()
{
return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiExecutePath);
}
第三步(若请求Web APi则启动Session)
protected void Application_PostAuthorizeRequest()
{
if (isWebAPiRequest())
{
HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
}
第四步(测试代码)
protected void Session_Start()
{
HttpContext.Current.Session.Add("xpy0928", "嗨-博客");
var session_value = HttpContext.Current.Session["xpy0928"];
}
Web APi全局启动Session(二)
之前我们在Web APi系列中讲到过HttpControllerRouteHandler,此类中的GetHttpHandler方法返回HttpControllerHandler的一个实例即HttpHandler,通过此HttpHandler是进入Web APi消息处理管道的入口点,我们可以使用在IHttpHandler上的Session实现IRquiressionstate接口即可。
第一步(启动Session)
protected void Application_PostAuthorizeRequest()
{
HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
第二步(自定义实现HttpHandler)
public class EnableSession_ControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public EnableSession_ControllerHandler(RouteData routeData)
: base(routeData)
{ }
}
第三步(获取HttpHandler)
public class EnableSession_ControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public EnableSession_ControllerHandler(RouteData routeData)
: base(routeData)
{ }
}
第四步(路由配置进行获取自定义RouteHandler)
routes.MapHttpRoute(
name: "DefaultAPi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = UrlParameter.Optional }
).RouteHandler = new EnableSession_HttpControllerRouteHandler();
第五步(在Web APi配置文件中实现自定义HttpControllerRouteHandler)
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 EnableSession_HttpControllerRouteHandler(), true));
}
config.MapHttpAttributeRoutes();
}
此时运行将出现如下错误:
第六步(测试代码)
public void Get()
{
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["xpy0928"] as int?;
httpContext.Session["xpy0928"] = "博客园";
var session_value = httpContext.Session["xpy0928"];
}
}
}
总结
以上两种方法皆可在Web APi中启动Session,你觉得那个简单就按照对应的来。我们需要注意一个问题是:在Web APi中,Web APi是不依赖于HttpContext,也就是HttpContext.Current肯定是为null的,我们要访问Session或者其他对象需要使用Rquest对象中的属性Properties来获得你想的值或者来设置值。
在Controller里:
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
var context = HttpContext.Current;
context.Session["a"] = "aaa";
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
var ses = HttpContext.Current.Session["a"];
return ses.ToString();
}
}
执行时出报异常,这时要在Global.asax里添加:开启Session功能
public class WebApiApplication : System.Web.HttpApplication
{
public override void Init()
{
this.PostAuthenticateRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
base.Init();
}
}
----------------------------------------------------------------------------------------------
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“sv”。
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class sv : Isv
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class sv : Isv
<system.serviceModel>
<services>
<service name="Tools.sv">
<endpoint address="" binding="webHttpBinding" bindingConfiguration=""
contract="Tools.Isv" />
</service>
</services>
<bindings />
<behaviors>
<endpointBehaviors>
<behavior name="">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints />
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"></serviceHostingEnvironment>
<services>
<service name="Tools.sv">
<endpoint address="" binding="webHttpBinding" bindingConfiguration=""
contract="Tools.Isv" />
</service>
</services>
<bindings />
<behaviors>
<endpointBehaviors>
<behavior name="">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints />
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"></serviceHostingEnvironment>