为什么ModelState在没有记录任何错误时无效?

时间:2014-10-12 20:02:14

标签: asp.net asp.net-mvc asp.net-mvc-4

我在验证我的ModelState登录功能时遇到了一些问题。

设置如下: 我有一个数据库表,其中包含大约6个将记录用户信息的属性。 (Id,用户名,电子邮件,密码,CreatedOn,DisabledUser)。我使用的是LocalDb功能和实体框架。

使用Repository模式与数据库进行交互。(IUserRepository用于定义我的操作,UserRepository用于我将Ninject注册为DI容器的具体实现)

User实体类的定义如下:

public class User
    {
        public Int32 Id { get; set; }
        public String Username { get; set; }
        public String Email { get; set; }
        public String Password { get; set; }
        public DateTime CreatedOn { get; set; }
        public Boolean DisabledUser { get; set; }
    }

要定义登录过程,我有一个如下定义的接口的具体实现:

public class FormsAuthProvider: IAuthProvider
    {
        public bool Authenticate(string username, string password)
        {
            bool result = FormsAuthentication.Authenticate(username, password);
            if (result)
            {
                FormsAuthentication.SetAuthCookie(username, false);
            }

            return result;
        }

    }

继续,我用来将数据从模型传递到视图的视图模型是

public class LoginViewModel
    {
        [Required]
        public String Username { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }

处理登录请求的控制器操作是:

[HttpPost]
        public ActionResult Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (authProvider.Authenticate(model.Username, model.Password))
                {
                    return Redirect(returnUrl ?? Url.Action("Index", "Account"));
                }
                else
                {
                    ModelState.AddModelError("", "User or password was incorrect");
                    return View();
                }      

            }
            else
            {
                return View();
            }
        }

视图

@model pRom.WebUI.Models.LoginViewModel

@{
    ViewBag.Title = "Log In";
    Layout = "~/Views/Shared/_AccountLayout.cshtml";
}

<h2>Login</h2>

<p>Please log in to access the administrative area:
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
        @Html.EditorForModel()
        <p><input type="submit" value="Log in" /></p> 
    }
</p>

在该页面上吐出的标记是:

<form action="/" method="post"><div class="editor-label"><label for="Username">Username</label></div>
<div class="editor-field"><input class="text-box single-line" data-val="true" data-val-required="The Username field is required." id="Username" name="Username" type="text" value="" /> <span class="field-validation-valid" data-valmsg-for="Username" data-valmsg-replace="true"></span></div>
<div class="editor-label"><label for="Password">Password</label></div>
<div class="editor-field"><input class="text-box single-line password" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" type="password" value="" /> <span class="field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span></div>
        <p><input type="submit" value="Log in" /></p> 
</form></p>

因此,尽管我确信用户和密码字段都与数据库中的内容相对应,但我总是将这一切带到我在else分支中添加的错误中。

我试图以某种方式调试它,看看是否有任何错误附加到ModelState但没有运气。尝试了一些我在SO上找到的东西,主要是在ModelState属性上进行迭代。

我被卡住了,你能指出我应该在哪里解决这个问题吗?谢谢。

编辑: 我已经做了一些调试,失败的地方是

bool result = FormsAuthentication.Authenticate(username, password);

因此模型验证工作正常,它是不具备的身份验证。我检查过本地人,传递的用于比较的字符串是数据库中的字段。

1 个答案:

答案 0 :(得分:1)

您正在使用FormsAuthentication.Authenticate(已过时),实际上是looks at the credentials stored in the web.config,因此这是最有可能发生的问题。

如果您正在尝试使用Membership API,则希望将FormsAuthentication.Authenticate替换为Membership.ValidateUser(使用相同的参数)。这需要您在web.config中设置提供程序。否则,您可能需要将Authenticate替换为您自己的自定义服务类。