我想构建一个登录表单,该表单显示在我站点中每个页面的侧栏中。如果用户输入了错误的用户/通行证,我希望错误显示在此表单上方(页面的其余部分保持原样),如果他成功登录,我希望表单更改为列表有关用户的信息(同样,页面的其余部分与登录前相同)。我正在使用带有默认Internet应用程序模板的MVC 3 Web应用程序项目。我有这个:
_Layout.cshtml
@{
if (User.Identity.IsAuthenticated)
{
Html.RenderAction("ShowUserInfo", "User");
}
else
{
Html.RenderAction("LogIn", "User");
}
}
UserController中
[ChildActionOnly]
public PartialViewResult ShowUserInfo()
{
// populate loggedInInfo from database based on
// User.Identity.Name
return PartialView("_LoggedInInfo", loggedInInfo);
}
private ActionResult RedirectToPrevious(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("index", "");
}
}
[ChildActionOnly]
public PartialViewResult LogIn()
{
return PartialView("_LogInForm");
}
//
// POST: /User/LogIn
[HttpPost]
public ActionResult LogIn(LogInModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToPrevious(returnUrl);
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
return RedirectToPrevious(returnUrl);
}
_LogInForm
@model MyProject.Models.LogInModel
<h2>Login</h2>
<p>
Please enter your username and password. @Html.ActionLink("Register", "register", "user") if you don't have an account.<br />
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
</p>
@using (Html.BeginForm("LogIn", "user")) {
html stuff
}
这几乎按预期工作,除了当我输入错误的用户名/密码时,页面只是以空表格重新加载并且不显示错误。我也尝试了其他一些东西,但是我得到的错误是我不能从局部视图发出重定向,或者我将部分视图(显示错误)显示为整个视图,因此它显示为单个页面,与网站的其余部分分开。如果我正确登录,一切正常。
如何才能在表单上方正确显示错误?我宁愿不使用任何Ajax或JQuery来执行此操作。
答案 0 :(得分:3)
问题似乎是你正在进行重定向,而不仅仅是返回appropriet视图。
添加模型错误后,您需要返回视图而不是执行重定向:
return View("LoginViewNameGoesHere")
所以你不想在这里返回局部视图,而是整个视图。
答案 1 :(得分:0)
执行时,RedirectToAction
和Redirect
,当前请求以http status code for redirection - 3xx结尾,告知浏览器将另一个请求发送到指定的网址。这意味着,当前请求的所有验证数据都将丢失,并且对登录URL进行全新的纯请求。你得到空的形式,没有错误。
您应该做的是在当前请求范围内呈现登录视图,而不是通过重定向。重新显示无效视图的一般模式
public ActionResult Login(LogInModel model)
{
if(ModelState.IsValid)
{
return RedirectToAction("Home");
}
return View(model); //! no redirection
}