69

我需要在会话(或 ASP.NET Web API 中的任何内容)中存储一些信息,我需要在每个 API 请求中检索这些信息。我们将有一个 api IIS 网站,并通过主机头添加多个网站绑定。当任何请求进入时,例如 api.xyz.com,将检查主机标头并将该网站信息存储在会话中,这些信息将在调用数据库时在每个后续 api 请求中使用。

我知道 ASP.NET Web API 中不支持会话。有没有其他方法可以处理这种情况?我可以在哪里存储可以在每个后续请求中检索的信息?

谢谢。

4

5 回答 5

112

在 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);
}

试一试 ;)

于 2013-02-23T08:35:03.050 回答
89

好吧,REST 的设计是无状态的。通过添加会话(或任何其他类型的),您将使其成为有状态的,并破坏了拥有 RESTful API 的任何目的。

RESTful 服务的整体理念是,每个资源都可以使用通用语法唯一地寻址以用于超媒体链接,并且每个 HTTP 请求本身应该携带足够的信息,以便其接收者对其进行处理,以与 HTTP 的无状态特性完全一致” .

因此,无论您在这里尝试使用 Web API 做什么,如果您希望拥有一个 RESTful API,很可能应该重新架构。

话虽如此,如果您仍然愿意走这条路,有一种将会话添加到 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();
于 2012-07-13T22:09:55.217 回答
33

在 WebApi 2 中,您可以将其添加到global.asax

protected void Application_PostAuthorizeRequest() 
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}

然后您可以通过以下方式访问会话:

HttpContext.Current.Session
于 2014-09-22T12:40:30.290 回答
3

如果数据足够小并且不存在安全问题,您可以使用 cookie。相同的基于 HttpContext.Current 的方法应该可以工作。

请求和响应 HTTP 标头也可用于在服务调用之间传递信息。

于 2012-10-05T19:10:47.693 回答
2

现在在 2017 年使用 ASP.Net Core,您可以按照此处的说明进行操作。

Microsoft.AspNetCore.Session 包提供用于管理会话状态的中间件。

启动.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 Core 中的会话和应用程序状态简介

已经在一个工作项目上测试过

于 2017-07-18T20:38:17.240 回答