【问题标题】:Validation not working on ViewModel验证不适用于 ViewModel
【发布时间】:2011-01-16 10:16:01
【问题描述】:

好的,我有一个看起来像这样的 ViewModel:

public class UserLogin
{
    [Required]
    public string EmailAddress { get; set; }

    [Required]
    public string Password { get; set; }
}

我的控制器如下所示:

[HttpPost]
public ActionResult LogIn(UserLogin model)
{
    if (!ModelState.IsValid)
    {
        // ...
    }
}

我的观点是这样的:

<% Html.BeginForm("Join", "User", FormMethod.Post); %>
    <%= Html.Hidden("ReturnUrl", Request.Url.AbsolutePath) %>

    <%= Html.TextBoxFor(c => c.EmailAddress, new { id = "join-emailaddress", @class = "text", uiHintText = "Email address" })%>
    <%= Html.ValidationMessageFor(c => c.EmailAddress, "*") %>

    <%= Html.PasswordFor(c => c.Password, new { id = "join-password", @class = "text", uiHintText = "Password" })%>
    <%= Html.ValidationMessageFor(c => c.Password, "*")%>

    <%= Html.PasswordFor(c => c.PasswordConfirm, new { id = "join-password-confirm", @class = "text", uiHintText = "Password (repeat)" })%>
    <%= Html.ValidationMessageFor(c => c.PasswordConfirm, "*")%>

    <input type="submit" value="Sign me up!" class="submit" />
<% Html.EndForm(); %>                

如果我在任何字段中都没有输入任何内容就发布表单,我会始终为“ModelState.IsValid”获得一个“真”值。

不应该是“假”吗,因为我已经将这些字段标记为“必填”并且没有输入任何值?

【问题讨论】:

    标签: c# asp.net-mvc validation asp.net-mvc-2 viewmodel


    【解决方案1】:

    查看 ASP.NET MVC 的最新 RC。它包括一些对此的修复。

    http://haacked.com/archive/2010/02/04/aspnetmvc2-rc2.aspx

    具体来说,来自发行说明:

    默认验证系统验证整个模型
    默认 ASP.NET MVC 1.0 中的验证系统 并且在 ASP.NET MVC 2 之前的预览中 到 RC 2 验证的唯一模型 发布到的属性 服务器。在 ASP.NET MVC 2 RC2 中,新的 行为是所有模型属性 当模型被验证时 验证,无论是否新 值已发布。

    有关此更改的更多信息,请参阅 Brad Wilson 博客上的以下帖子:

    ASP.NET MVC 中的输入验证与模型验证
    http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html

    【讨论】:

    • 我升级到 ASP.NET MVC 2 RC 2,但我仍然遇到完全相同的问题。升级似乎没有改变任何事情。
    • 我认为它现在已修复,但一个奇怪的修复...请参阅我在 @H_Sampat 的回答下的评论。
    【解决方案2】:

    我之前也遇到过同样的问题,但我使用的是 ASP.NET MVC1。 但是我通过在 Global.asax.vb 文件中添加以下代码解决了这个问题。

    Sub Application_Start()
        RegisterRoutes(RouteTable.Routes)
    
        'Added following line
        ModelBinders.Binders.DefaultBinder = New Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder()        
    End Sub
    

    您需要导入 Microsoft.Web.Mvc.DataAnnotations.dll。你可以从http://aspnet.codeplex.com/releases/view/24471获得它

    【讨论】:

    • 已修复!我在 Application_Start 函数中添加了以下语句:ModelBinders.Binders.DefaultBinder = new System.Web.Mvc.DefaultModelBinder();。我想知道为什么这是必要的。有时间会再研究一下。
    • 呃……我错了。第二次运行该项目,它又给我一个“ModelState.IsValid”的“真实”...我必须仔细检查我所做的所有更改,并找出它崩溃的原因...跨度>
    【解决方案3】:

    我找出了我的特定问题的原因。

    在我的 ViewModel 属性上使用 [Required] 属性时,我为错误指定了资源类型和资源名称。

    例子:

    [Required(ErrorMessageResourceName = "FirstNameError", 
              ErrorMessageResourceType = typeof(MyResourceFile))]
    public string FirstName { get; set; }
    

    但是我忽略了将 FirstNameError 资源设为“公共”;它仍被标记为“内部”,因此无法访问。

    将其设为公开后,一切正常,并且 ModelState.IsValid 包含正确的值。

    我很惊讶没有出现任何错误,而且这无声无息地失败了,但现在我知道为什么了。

    (是的,我应该从一开始就提到我正在使用资源。我错误地认为这无关紧要,但事实证明它非常相关。)

    【讨论】:

    • 如果您认为这是一个真正的错误,请确保让 Phil Haack 知道这件事。 haacked.com/contact.aspx。将其纳入最终版本会很高兴。
    • 好主意!我已经给菲尔发了一条消息。
    猜你喜欢
    • 1970-01-01
    • 2014-08-17
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    相关资源
    最近更新 更多