访问ASP.NET Web API会话
访问ASP.NET Web API会话
我知道会话和REST不完全适应,但是使用新的Web API访问会话状态是否不可能? HttpContext.Current.Session
始终为空。 </ p>
您可以使用自定义的RouteHandler访问会话状态。
// In global.asax public class MvcApp : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { var route = routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); route.RouteHandler = new MyHttpControllerRouteHandler(); } } // Create two new classes public class MyHttpControllerHandler : HttpControllerHandler, IRequiresSessionState { public MyHttpControllerHandler(RouteData routeData) : base(routeData) { } } public class MyHttpControllerRouteHandler : HttpControllerRouteHandler { protected override IHttpHandler GetHttpHandler( RequestContext requestContext) { return new MyHttpControllerHandler(requestContext.RouteData); } } // Now Session is visible in your Web API public class ValuesController : ApiController { public string Get(string input) { var session = HttpContext.Current.Session; if (session != null) { if (session["Time"] == null) session["Time"] = DateTime.Now; return "Session Time: " + session["Time"] + input; } return "Session is not availabe" + input; } }
此处找到:http://techhasnoboundary.blogspot.com/2012/03/mvc-4-web-api-access-session.html
MVC
对于MVC项目,请进行以下更改(WebForms和Dot Net Core的解答如下):
WebApiConfig.cs
public static class WebApiConfig { public static string UrlPrefix { get { return "api"; } } public static string UrlPrefixRelative { get { return "~/api"; } } public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication { ... protected void Application_PostAuthorizeRequest() { if (IsWebApiRequest()) { HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); } } private bool IsWebApiRequest() { return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative); } }
此解决方案具有额外的好处,我们可以获取JavaScript中的基本URL,以便进行AJAX调用:
_Layout.cshtml
@RenderBody() @RenderSection("scripts", required: false)
然后,在我们的JavaScript文件/代码中,我们可以进行WebApi调用,可以访问会话:
$.getJSON(apiBaseUrl + '/MyApi') .done(function (data) { alert('session data received: ' + data.whatever); }) );
WebForms
执行上述操作,但将WebApiConfig.Register函数更改为接受RouteCollection:
public static void Register(RouteCollection routes) { routes.MapHttpRoute( name: "DefaultApi", routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
然后在Application_Start中调用以下内容:
WebApiConfig.Register(RouteTable.Routes);
Dot Net Core
添加Microsoft.AspNetCore.Session NuGet包,然后进行以下代码更改:
Startup.cs
在ConfigureServices函数中在services对象上调用AddDistributedMemoryCache和AddSession方法:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); ... services.AddDistributedMemoryCache(); services.AddSession();
在Configure函数中添加一个调用UseSession:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseSession(); app.UseMvc();
SessionController.cs
在控制器中,在顶部添加using语句:
using Microsoft.AspNetCore.Http;
然后在你的代码中使用HttpContext.Session对象,像这样:
[HttpGet("set/{data}")] public IActionResult setsession(string data) { HttpContext.Session.SetString("keyname", data); return Ok("session data set"); } [HttpGet("get")] public IActionResult getsessiondata() { var sessionData = HttpContext.Session.GetString("keyname"); return Ok(sessionData); }
现在,您应该能够访问:
http://localhost:1234/api/session/set/thisissomedata
然后转到此URL将其提取出来:
http://localhost:1234/api/session/get
有关在Dot Net Core中访问会话数据的更多信息,请访问此处:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state
性能问题
请查看下面Simon Weaver的答案,了解有关性能的信息。如果您在WebApi项目中访问会话数据,可能会导致严重的性能后果 - 我看到ASP.NET对并发请求强制执行200毫秒延迟。如果您有许多并发请求,这可能会累积并成为灾难性的问题。
安全隐患
确保您根据用户锁定资源 - 认证用户不应该能够检索他们没有访问权限的WebApi数据。
阅读Microsoft关于ASP.NET Web API中身份验证和授权的文章 - https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
阅读Microsoft关于避免跨站请求伪造攻击的文章(简而言之,查看AntiForgery.Validate方法) - https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks