我正在使用 MVC 4 构建一个单页应用程序。对于登录功能,我对此操作执行 jquery ajax POST:
[HttpPost] [AllowAnonymous]
public JsonResult JsonLogin(LogInFormViewModel form)
{
...
//If user authenticates
formAuthentication.SetAuthCookie(this.HttpContext,
UserAuthenticationTicketBuilder.CreateAuthenticationTicket(
user));
return Json(new { success = true, viewResult = this.RenderPartialView("UserStatusBar", null) });
...
}
RenderPartialView()
是一个自定义扩展,它只是将我的剃刀部分视图呈现为字符串。
“UserStatusBar”是任何网站顶部的标准栏,如果用户未通过身份验证,则显示登录/注册,如果用户未通过身份验证,则显示注销/欢迎:
@if (Request.IsAuthenticated)
{
<div id="LoggedIn">
<a class="logoutLink" href="#">Log out</a>
<span>Welcome, @User.Identity.Name</span>
</div>
} else {
<div id="notLoggedIn">
<a class="loginLink popupLink" href="#">Log in</a>
<a class="registerLink popupLink" href="#">Register</a>
</div>
}
在我的 ajax 成功处理程序中,我做了这样的事情来在用户登录或注销后异步重新呈现用户状态栏:
success: function (result) {
if (result.success) {
$('#userStatusBar').empty().html(result.viewResult, null);
}
}
唯一的问题是,每当代码进入我的自定义扩展RenderPartialView()
时,Request.IsAuthenticated
它仍然与 ajax 调用之前相同,因此在下一个请求之前它不会重新呈现正确的状态栏。
我该如何解决这个问题,因为Request.IsAuthenticated
它是只读的,我不能在设置授权 cookie 后简单地设置它。我唯一能做的就是设置一个 TempData 属性并在渲染 UserStatusBar 时检查它:
@if (Request.IsAuthenticated || (TempData["AjaxAuthenticated"] != null && (bool)TempData["AjaxAuthenticated"]))
{
<logged in html>
} else <logged out html>
但这是有问题的,因为注销时会发生相反的情况;在重新渲染状态栏并且它再次为状态栏渲染不正确的标记直到下一个请求Request.IsAuthenticated
之后仍然为真。formsAuthentication.SignOut()
我似乎想不出解决这个问题的方法,因为我还需要永久链接才能工作,所以 Request.IsAuthenticated 是我在这种情况下要查看的那个。