Session ASP.NET Web API会话还是什么?

Session ASP.NET Web API会话还是什么?,session,asp.net-web-api,Session,Asp.net Web Api,我需要在会话(或ASP.NET Web API中的任何内容)中存储一些信息,以便在每个API请求中检索这些信息。我们将有一个api IIS网站和多个网站绑定将通过主机头添加。当任何请求(例如api.xyz.com)传入时,将检查主机头并将该网站信息存储在会话中,该会话将在调用数据库时用于后续的每个api请求 我知道ASP.NET Web API中不支持会话。有没有其他办法来处理这种情况?在哪里可以存储可以在每个后续请求中检索的信息 谢谢。 好吧,REST按设计是无状态的。通过添加session(

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

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

谢谢。

好吧,REST按设计是无状态的。通过添加session(或其他类似的东西),您正在使它成为有状态的,并且违背了使用restfulapi的任何目的

RESTful服务的整体理念是,每个资源都是唯一可寻址的,使用一种用于超媒体链接的通用语法,每个HTTP请求本身都应该携带足够的信息,以便其接收者处理它,从而与HTTP的无状态性质完全协调”

因此,无论您试图在这里使用Web API做什么,如果您希望使用RESTful API,都应该重新构建它

话虽如此,如果您仍然愿意走这条路,那么有一种将会话添加到Web API的黑客方法,Imran在这里发布了该方法

代码(尽管我并不推荐):

公共类MyHttpControllerHandler
:HttpControllerHandler,iRequiresessionState
{
公共MyHttpControllerHandler(RouteData RouteData):基础(RouteData)
{ }
}
公共类MyHttpControllerOutehandler:HttpControllerOutehandler
{
受保护的覆盖IHttpHandler GetHttpHandler(RequestContext RequestContext)
{
返回新的MyHttpControllerHandler(requestContext.RoutedData);
}
}
公共类值控制器:ApiController
{
公共字符串获取(字符串输入)
{
var session=HttpContext.Current.session;
if(会话!=null)
{
if(会话[“时间”]==null)
{
会话[“时间”]=DateTime.Now;
}
返回“会话时间:”+会话[“时间”]+输入;
}
return“会话不可用”+输入;
}
}
然后将HttpControllerHandler添加到API路由:

route.RouteHandler=新的MyHttpControllerOutehandler();

如果数据足够小且不存在安全问题,则可以使用cookie。相同的HttpContext。基于当前的方法应该有效

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

在Global.asax中添加

public override void Init()
{
this.PostAuthenticateRequest+=mvcapapplication\u PostAuthenticateRequest;
base.Init();
}
void mvcapapplication\u PostAuthenticateRequest(对象发送方,事件参数e)
{
System.Web.HttpContext.Current.SetSessionStateBehavior(
SessionStateBehavior.必选);
}

试一试;)

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

protected void Application_PostAuthorizeRequest() 
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
然后,您可以通过以下方式访问会话:

HttpContext.Current.Session

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

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();
}
从文档中:


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

谢谢。非常有用。我不反对REST,但我想为每个api请求保存数据库trip。我们有一个与api域关联的唯一id,我需要为每个api请求将该id传递给数据库调用。如果我不使用会话,我最终会为每个api请求重复相同的逻辑api请求。顺便问一下,是否有一种方法可以覆盖类似于asp.net中的PreRequestHandlerExecute,并在会话中存储我希望在每个api请求中检索的数据?控制器将很难以这种方式进行单元测试。我将添加一个HttpContextBase(或HttpSessionStateBase)参数,并使用DI将其解析为应用程序的新HttpContextWrapper(HttpContext.Current)。然后在单元测试中可以对其进行模拟。正如@Filip所说,我们不要遵循此路径(将会话添加到假定为无状态的Web API)但是同一个Filip有一篇关于Web API缓存的好文章:我在gitHub中为他添加了一些功能,现在它为登录用户支持分离的输出缓存:注意:我仍在改进代码并测试它是否存在任何可能的安全漏洞。我发现Web API控制器非常有用,因为我可以设置一个del或view模型作为返回类型,它与我的javascript框架配合得很好,所以我不必在普通控制器中创建JsonResults。从这个意义上说,它们不是真正的无状态REST API控制器,而是AJAX请求的更自然的端点,因此会话状态仍然是我想要的。这对R非常有用EST是您在第一个请求上对用户进行身份验证,然后使用身份验证状态知道他们在所有后续请求上都经过身份验证。这很有效!非常感谢!顶部的答案不起作用,因为route.RouteHandler似乎不起作用,因为它与Web API中的类型不同。此答案解决了问题。+1 I如果你知道自己在做什么,你认为在某些特殊情况下在Web Api中使用会话是可以的。我使用了它,我的一些页面变得非常慢。最好测试请求是否是Web Api:if(HttpContext.Current.request.Url.AbsolutePath.StartsWith(“/Api/”)如何为此设置会话超时?@nima[…]中有一些额外的字符(“/api”):我知道这很旧,但可以帮助其他人阅读这篇文章。如果您使用XDomainRequest执行CORS ajax请求,那么IE8/9中使用cookie有一个限制。您可以阅读更多