我的MasterPage中有一个登录框。每当登录信息不正确时,我都会对ViewData["loginError"]
进行定价,以向用户显示错误消息。
登录是UserController的操作,因此包含登录的表单为action = "/User/Login"
。
由于用户可以尝试从任何页面登录,如果成功,我会将他重定向到他的个人页面,但如果出现错误,我希望他留在他尝试登录的同一页面上。我发现这有效:
return Redirect(Request.UrlReferrer.ToString());
但似乎因为我没有返回正确的视图,ViewData上的数据会丢失,所以我无法显示错误消息。
关于如何解决这个问题和类似问题的任何建议?
由于
答案 0 :(得分:16)
您可能希望使用TempData
属性,这将持久保存到下一个HTTP请求。
答案 1 :(得分:2)
为什么不通过AJAX处理登录而不是完整的帖子?您可以通过JSON轻松提供状态,重定向URL和任何错误消息。
public ActionResult Logon( string username, string password )
{
...
// Handle master page login
if (Request.IsAjaxRequest())
{
if (success)
{
return Json( new { Status = true, Url = Url.Action( "Index", "Home" ) } );
}
else
{
return Json( new { Status = false, Message = ... } );
}
}
else // handle login page logon or no javascript
{
if (success)
{
return RedirectToAction( "Index", "Home" );
}
else
{
ViewData["error"] = ...
return View("Logon");
}
}
}
客户端
$(function() {
$('#loginForm input[type=submit]').click( function() {
$('#loginError').html('');
$.ajax({
url: '<%= Url.Action("Logon","Account") %>',
dataType: 'json',
type: 'post',
data: function() { return $('#loginForm').serialize(); },
success: function(data,status) {
if (data.Status) {
location.href = data.Url;
}
else {
$('#loginError').html( data.Message );
}
}
});
return false;
});
});
答案 2 :(得分:1)
通常对于大多数网站来说,当用户无法进行身份验证时(由于密码等),它将转到另一个帮助用户的页面(如密码检索,或要求用户注册),这很少见留在同一页面。我想你可以重新考虑一下你真的需要你正在使用的导航。
好的,如果您真的想坚持自己的模型,那么一个解决方案就是您可以将登录错误附加到URL。例如,http://www.example.com/index.aspx?login_error=1表示发生错误,您可以使用BEGIN_REQUEST(或HTTP模块)捕获此错误,并告知模型状态错误:
ModelState.AddModelError(...);
BTW,添加模型错误实际上是一种更恰当的方式来通知视图有关任何错误而不是使用ViewState(这类似于抛出异常vs返回关于过去执行结果的整数)。
虽然使用AJAX登录(正如tvanfosson所建议)是完全可以实现的,并且它有时在用户体验方面表现出色,但经典的全帖仍然是不可替代的(考虑一些用户将禁用javascript,甚至在我的转储WM6手机上没有' t支持javascript)。
答案 3 :(得分:1)
我很困惑。不
return View();
只需将当前页面返回给您?
因此,在您的情况下,当登录失败时,请设置您的viewdata并调用return View();
即
if (!FailedLogin) {
//Go to success page
}else{
//Add error to View Data or use ModelState to add error
return View();
}
您使用的是[授权]装饰器吗? MVC登录过程会自动提示登录页面,然后返回您尝试执行的控制器操作。减少了很多重定向。
答案 4 :(得分:1)
以下示例有望帮助您解决此问题:
<强> View.aspx 强>
<%= Html.ValidationSummary("Login was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<%= Html.TextBox("username") %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="password">Password:</label>
<%= Html.Password("password") %>
<%= Html.ValidationMessage("password") %>
</p>
<p>
<%= Html.CheckBox("rememberMe") %> <label class="inline" for="rememberMe">Remember me?</label>
</p>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
<% } %>
<强> AccountController.cs 强>
private bool ValidateLogOn(string userName, string password)
{
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", "You must specify a username.");
}
if (String.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "You must specify a password.");
}
if (!MembershipService.ValidateUser(userName, password))
{
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}
return ModelState.IsValid;
}
重定向操作后,您将无法捕获ViewData中添加的信息。所以正确的方法是返回相同的View()并使用ModelState进行错误,如“xandy”所述。
希望这会让你在表单验证方面领先一步。