我需要在会话中(或者在ASP.NET Web API中)存储我需要在每个API请求中检索的一些信息。我们将有一个api IIS网站,并通过主机头添加多个网站绑定。例如,当有任何请求进入时,api.xyz.com将检查主机头并将该网站信息存储在会话中,以便在对数据库进行调用时用于每个后续api请求。ASP.NET Web API会话什么的?
我知道ASP.NET Web API中不支持会话。有没有其他办法来处理这种情况?我可以在哪里存储可在每个后续请求中检索的信息?
谢谢。
我需要在会话中(或者在ASP.NET Web API中)存储我需要在每个API请求中检索的一些信息。我们将有一个api IIS网站,并通过主机头添加多个网站绑定。例如,当有任何请求进入时,api.xyz.com将检查主机头并将该网站信息存储在会话中,以便在对数据库进行调用时用于每个后续api请求。ASP.NET Web API会话什么的?
我知道ASP.NET Web API中不支持会话。有没有其他办法来处理这种情况?我可以在哪里存储可在每个后续请求中检索的信息?
谢谢。
那么,设计中的REST是无状态的。通过添加会话(或其他类型的任何其他类型),您将使其成为有状态的,并打败拥有RESTful API的任何目的。
RESTful服务的整体思路是,每个资源使用通用语法在超媒体的使用是唯一可寻址链接和每个HTTP请求应为它的接收方处理它是完全和谐本身携带足够的信息与HTTP的”无状态特性。
所以,无论你想在这里使用Web API做的,应该最有可能被重新architectured如果你想有一个RESTful API。
随着中说,如果你仍然愿意沿着这条路走下去,这是一种冒险的方式裂变与Web API,并且它已经发布的伊姆兰这里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();
如果数据足够小并且不存在安全问题,则可以使用cookie。基于相同的基于HttpContext.Current的方法应该可以工作。
请求和响应HTTP标头也可用于在服务调用之间传递信息。
我知道这是旧的,但可以帮助任何人阅读这些东西。如果您使用XDomainRequest执行CORS ajax请求,那么对于使用IE8/9中的cookie有一个限制。你可以阅读更多关于它[这里](http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx) – elvin 2014-09-15 23:52:03
在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);
}
给它一个镜头;)
这工作!非常感谢你!最佳答案自route.RouteHandler似乎无法正常工作,因为它不是在Web API中的类型。这个答案解决了这个问题。 – Tikkes 2013-04-09 12:13:51
+1我认为如果你知道自己在做什么,可以在某些特殊情况下使用Web API中的Session。 – nima 2013-05-28 12:32:40
我用这个,我的一些网页变得很慢。最好测试请求是否是Web API:if(HttpContext.Current.Request.Url.AbsolutePath.StartsWith(“/ api /”)) – nima 2013-06-01 14:54:04
在2的WebAPI,你可以将它添加到Global.asax中
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
,那么你可以通过以下方式访问会话:
HttpContext.Current.Session
这是如何在其他答案中添加任何内容的? – 2015-01-21 14:22:48
@eddie_cat简单地说,他把它放在PostAuthorize中。尽管如此,为了使这一点更好,他可以指出并添加条件检查,如果请求是尼玛指出的api请求。 – Suamere 2015-04-29 21:07:27
现在在2017与ASP.Net核心,你可以做到这一点,这里解释。
Microsoft.AspNetCore.Session包提供用于管理会话状态的中间件。
Introduction to session and application state in ASP.NET Core
上一个工作项目
由于已经测试。很有帮助。我不会违反REST,但我想为每个api请求保存数据库行程。我们有唯一的id与api域相关联,这个域需要传递给每个api请求的数据库调用。如果我不使用会话,我最终会为每个api请求重复相同的逻辑。 BTW有没有一种方法可以覆盖类似于我们在asp.net中的PreRequestHandlerExecute,并将数据存储在我想要在每个api请求中检索的会话中? – user1186065 2012-07-16 15:46:22
控制器将很难以这种方式进行单元测试。我将在控制器构造函数中添加一个HttpContextBase(或HttpSessionStateBase)参数,并使用DI将其解析为应用程序的新HttpContextWrapper(HttpContext.Current)。然后在单元测试中,你可以嘲笑它。 – 2012-10-05 19:08:38
正如@Filip所说的,让我们不要按照这个路径(向Web API添加应该是无状态的会话)。但同样的Filip有一篇关于Web API缓存的好文章:http://goo.gl/2rnfI 我在gitHub中分叉了他并为源代码添加了一些功能,现在它支持登录用户的分离输出缓存:http://goo.gl/oW4hX 注意:我仍在改进代码并针对任何可能的安全漏洞进行测试。 – Tohid 2012-12-28 15:26:22