我需要在 session(or Web API 中的 session(or 中存储一些我需要在每个 API 请求中检索的信息。我们将有一个 api IIS 网站,并将通过主机头添加多个网站绑定。例如,当任何请求进入 api.xyz.com 时,将检查主机头并将该网站信息存储在会话中,该会话将在调用数据库时在每个后续 api 请求中使用。
我知道 ASP.NET Web API 中没有对会话的支持。有没有其他方法来处理这种情况?我在哪里可以存储可以在每个后续请求中检索的信息?
谢谢。
好吧,REST 设计是无状态的。通过添加会话(或其他类似的东西),您可以使其成为有状态并且无法使用 RESTful API。
RESTful 服务的整体思想是每个资源都是唯一可寻址的,使用通用语法在超媒体链接中使用,并且每个 HTTP 请求应该自己携带足够的信息,以便其接收者处理它以与 HTTP 的无状态特性完全协调“ 。
因此,无论您在此处尝试使用 Web API,如果您希望拥有 RESTful API,那么很可能是 re-architectured。
话虽如此,如果你仍然愿意沿着那条路走下去,那么就有一种将会话添加到 Web API 的 hacky 方式,它已经由 Imran 发布了http://forums.asp.net/t/1780385.aspx/1
代码(虽然我不会真的推荐):
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); } } 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; } }
然后将 HttpControllerHandler 添加到您的 API 路由:
route.RouteHandler = new MyHttpControllerRouteHandler();
在 Global.asax 添加
public override void Init() { this.PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest; base.Init(); } void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) { System.Web.HttpContext.Current.SetSessionStateBehavior( SessionStateBehavior.Required); }
试一试 ;)
在 WebApi 2 中,您可以将其添加到global.asax
protected void Application_PostAuthorizeRequest() { System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required); }
然后您可以通过以下方式访问会话:
HttpContext.Current.Session
如果数据足够小并且不存在安全问题,则可以使用 cookie。同样的基于_1 的方法应该有效。
请求和响应 HTTP 标头也可用于在服务调用之间传递信息。
现在 2017 年的 ASP.Net 核心,您可以按照此处的说明进行操作。
Microsoft.AspNetCore.Session 包提供用于管理会话状态的中间件。
Startup.cs
public void ConfigureServices(IServiceCollection services) { // Adds a default in-memory implementation of IDistributedCache. services.AddDistributedMemoryCache(); services.AddSession(options => { // Set a short timeout for easy testing. options.IdleTimeout = TimeSpan.FromSeconds(10); options.Cookie.HttpOnly = true; }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseSession(); }
来自文件:ASP.NET 核心中的会话和应用程序状态简介
已经在一个工作项目上测试过
5 回答
好吧,REST 设计是无状态的。通过添加会话(或其他类似的东西),您可以使其成为有状态并且无法使用 RESTful API。
RESTful 服务的整体思想是每个资源都是唯一可寻址的,使用通用语法在超媒体链接中使用,并且每个 HTTP 请求应该自己携带足够的信息,以便其接收者处理它以与 HTTP 的无状态特性完全协调“ 。
因此,无论您在此处尝试使用 Web API,如果您希望拥有 RESTful API,那么很可能是 re-architectured。
话虽如此,如果你仍然愿意沿着那条路走下去,那么就有一种将会话添加到 Web API 的 hacky 方式,它已经由 Imran 发布了http://forums.asp.net/t/1780385.aspx/1
代码(虽然我不会真的推荐):
然后将 HttpControllerHandler 添加到您的 API 路由:
在 Global.asax 添加
试一试 ;)
在 WebApi 2 中,您可以将其添加到global.asax
然后您可以通过以下方式访问会话:
如果数据足够小并且不存在安全问题,则可以使用 cookie。同样的基于_1 的方法应该有效。
请求和响应 HTTP 标头也可用于在服务调用之间传递信息。
现在 2017 年的 ASP.Net 核心,您可以按照此处的说明进行操作。
Microsoft.AspNetCore.Session 包提供用于管理会话状态的中间件。
Startup.cs
来自文件:ASP.NET 核心中的会话和应用程序状态简介
已经在一个工作项目上测试过