我知道会话和REST并不完全是齐头并进的,但是使用新的Web API访问会话状态是不可能的吗?session总是空的。
当前回答
要解决这个问题:
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
在Global.asax.cs
其他回答
回到基础,为什么不保持它的简单和存储会话值在一个隐藏的html值传递给你的API?
控制器
public ActionResult Index()
{
Session["Blah"] = 609;
YourObject yourObject = new YourObject();
yourObject.SessionValue = int.Parse(Session["Blah"].ToString());
return View(yourObject);
}
cshtml
@model YourObject
@{
var sessionValue = Model.SessionValue;
}
<input type="hidden" value="@sessionValue" id="hBlah" />
Javascript
$(文件)。准备(函数(){
var sessionValue = $('#hBlah').val();
alert(sessionValue);
/* Now call your API with the session variable */}
}
你说得对,REST是无状态的。如果您使用会话,处理将变成有状态的,后续请求将能够使用状态(来自会话)。
为了给会话补水,您需要提供一个键来关联状态。在普通的asp.net应用程序中,该密钥是通过使用cookie (cookie-sessions)或url参数(无cookie会话)来提供的。
如果你需要一个会话而不是休息,那么会话在基于rest的设计中是无关紧要的。如果您需要一个会话进行验证,则使用令牌或通过IP地址授权。
Mark,如果你检查nerddinner MVC示例,逻辑几乎是一样的。
您只需要检索cookie并在当前会话中设置它。
Global.asax.cs
public override void Init()
{
this.AuthenticateRequest += new EventHandler(WebApiApplication_AuthenticateRequest);
base.Init();
}
void WebApiApplication_AuthenticateRequest(object sender, EventArgs e)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
SampleIdentity id = new SampleIdentity(ticket);
GenericPrincipal prin = new GenericPrincipal(id, null);
HttpContext.Current.User = prin;
}
enter code here
您必须定义“SampleIdentity”类,可以从nerddinner项目中借用这个类。
我采用了@LachlanB方法,当请求上有会话cookie时,会话确实是可用的。缺失的部分是会话cookie是如何第一次发送到客户端?
我创建了一个HttpModule,它不仅启用httpessionstate可用性,而且还在创建新会话时向客户端发送cookie。
public class WebApiSessionModule : IHttpModule
{
private static readonly string SessionStateCookieName = "ASP.NET_SessionId";
public void Init(HttpApplication context)
{
context.PostAuthorizeRequest += this.OnPostAuthorizeRequest;
context.PostRequestHandlerExecute += this.PostRequestHandlerExecute;
}
public void Dispose()
{
}
protected virtual void OnPostAuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (this.IsWebApiRequest(context))
{
context.SetSessionStateBehavior(SessionStateBehavior.Required);
}
}
protected virtual void PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (this.IsWebApiRequest(context))
{
this.AddSessionCookieToResponseIfNeeded(context);
}
}
protected virtual void AddSessionCookieToResponseIfNeeded(HttpContext context)
{
HttpSessionState session = context.Session;
if (session == null)
{
// session not available
return;
}
if (!session.IsNewSession)
{
// it's safe to assume that the cookie was
// received as part of the request so there is
// no need to set it
return;
}
string cookieName = GetSessionCookieName();
HttpCookie cookie = context.Response.Cookies[cookieName];
if (cookie == null || cookie.Value != session.SessionID)
{
context.Response.Cookies.Remove(cookieName);
context.Response.Cookies.Add(new HttpCookie(cookieName, session.SessionID));
}
}
protected virtual string GetSessionCookieName()
{
var sessionStateSection = (SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");
return sessionStateSection != null && !string.IsNullOrWhiteSpace(sessionStateSection.CookieName) ? sessionStateSection.CookieName : SessionStateCookieName;
}
protected virtual bool IsWebApiRequest(HttpContext context)
{
string requestPath = context.Request.AppRelativeCurrentExecutionFilePath;
if (requestPath == null)
{
return false;
}
return requestPath.StartsWith(WebApiConfig.UrlPrefixRelative, StringComparison.InvariantCultureIgnoreCase);
}
}
要解决这个问题:
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
在Global.asax.cs
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何修改标签文本?
- 我如何使用IValidatableObject?
- 在EF中更新父实体时如何添加/更新子实体
- ASP。NET身份的默认密码散列器-它是如何工作的,它是安全的?
- 如何写一个JSON文件在c# ?
- Visual Studio - Resx文件默认“内部”为“公共”
- 用c#解析JSON
- ASP是什么?NET Identity的IUserSecurityStampStore<TUser>接口?
- net HttpClient。如何POST字符串值?
- ASP。网网络。config: configSource vs.文件属性
- 在Linq中转换int到字符串到实体的问题
- <system. >之间的差异。web>和<system.webServer>?
- 为什么ASP。NET web表单需要Runat="Server"属性吗?
- 使用不同的Web。在开发和生产环境中进行配置