我正在爲我的網站編寫登錄功能。當用戶請求受我的[CustomAuthorize]
屬性限制的視圖時,用戶將被正確重定向到/Login/Index
視圖,並附加查詢字符串(?ReturnUrl=%2fRestricted%2fView
)。MVC3 - 回傳後保留'returnUrl'?
但這裏有一個問題...
當用戶試圖登錄,並有一個驗證錯誤。發佈請求會導致回發(duh),並且附加的查詢字符串將從Url中消失。
- 如何在回發後保留查詢字符串?
CustomAuthorize.cs:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.User.Identity.IsAuthenticated)
{
var customIdentity = (CustomIdentity)httpContext.User.Identity;
var customPrincipal = new CustomPrincipal(customIdentity);
if (customIdentity.IsAdmin)
{
httpContext.User = customPrincipal;
Thread.CurrentPrincipal = customPrincipal;
}
}
return base.AuthorizeCore(httpContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var urlRequested = filterContext.HttpContext.Request.Path;
//urlRequested contains "/Restricted/View"
//Do something with 'urlRequested' here, or?
base.HandleUnauthorizedRequest(filterContext);
}
}
登錄/索引視圖:
<body>
@using (Html.BeginForm("Index", "Login"))
{
<div>
@Html.LabelFor(model => model.UserName)
</div>
<div>
@Html.EditorFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
</div>
<div>
@Html.LabelFor(model => model.Password)
</div>
<div>
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</div>
<div>
@Html.LabelFor(model => model.RememberMe)
</div>
<div>
@Html.EditorFor(model => model.RememberMe)
@Html.ValidationMessageFor(model => model.RememberMe)
</div>
<p>
<input type="submit" value="Login!" />
</p>
@Html.ValidationSummary(true)
}
</body>
登錄/索引控制器動作:
[HttpPost]
public ActionResult Index(LoginModelBinding login, string returnUrl)
{
if (ModelState.IsValid)
{
if (Service.CheckUser(login.UserName, login.Password))
{
String loginError;
CustomAuthorization.Login(login.UserName, login.Password, out loginError);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "MitTeam");
}
ModelState.AddModelError("", "The entered user name or password is incorrect");
}
return View(login);
}
SOLUTION: 按納文的回答我修改這樣的代碼:
public static void SaveReturnUrl(this Controller controller, string returnUrl, bool showAfterRedirect = true)
{
if (showAfterRedirect)
{
controller.TempData["returnUrl"] = returnUrl;
}
else
{
controller.ViewData["returnUrl"] = returnUrl;
}
}
public static string RetrieveReturnUrl(this Controller controller)
{
var message = controller.ViewData.ContainsKey("returnUrl") ? controller.ViewData["returnUrl"] : controller.TempData.ContainsKey("returnUrl") ? controller.TempData["returnUrl"] : null;
return message as string;
}
有了這兩個擴展方法,我可以保存和檢索我的登錄控制方法/行動RETURNURL。
var previousReturnUrl = this.RetrieveReturnUrl();
if(!ModelState.IsValid)
{
if(string.IsNullOrEmpty(previousReturnUrl))
{
this.SaveReturnUrl(returnUrl);
}
return View(login);
}
而且,如果ModelState中是有效的,我只是叫this.RetrieveReturnUrl
和解碼,所以我也可以把用戶在登錄成功的事件:
登錄POST方法。
謝謝! 'ViewContext.TempData'幫助了我很多!將用我的解決方案編輯我的問題。 – KristianB 2012-04-23 08:15:06