【问题标题】:MVC 3 Validation - Only show error messages after lost focus or submit?MVC 3 验证 - 仅在失去焦点或提交后显示错误消息?
【发布时间】:2011-08-28 10:03:18
【问题描述】:

我已经在我的 MVC 3 应用程序中使用 DataAnnotations(必需、字符串长度等)设置了实体,并且 MVC 页面适当地显示了验证错误消息。但是,在用户有机会输入无效值之前,一旦页面加载到新表单上,就会显示错误消息。

几年前我使用过 JQuery 验证,并且只能在用户失去对某个字段的关注或尝试提交表单后才显示错误消息。事实上,我认为这是默认行为。

在 MVC 3 中是否可以使用 DataAnnotations 做同样的事情?

编辑:这是 HTML

<div class="form horizontal floated w50p">
<h3>Billing Information</h3>
@using(Html.BeginForm()){
    <div class="item">
        <div class="label">
            <label>* First Name</label></div>
        <div class="value">@Html.TextBoxFor(x => x.Name)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.Name)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>* Address 1</label></div>
        <div class="value">@Html.TextBoxFor(x => x.Street1)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.Street1)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>Address 2</label></div>
        <div class="value">@Html.TextBoxFor(x => x.Street2)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>Address 3</label></div>
        <div class="value">@Html.TextBoxFor(x => x.Street3)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>City</label></div>
        <div class="value">@Html.TextBoxFor(x => x.City)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.City)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>State/Province/Region</label></div>
        <div class="value">@Html.TextBoxFor(x => x.StateProv)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.StateProv)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>Zip / Postal Code</label></div>
        <div class="value">@Html.TextBoxFor(x => x.PostalCode)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.PostalCode)</div>
    </div>
    <div class="item">
        <div class="label">
            <label>* Contact Phone</label></div>
        <div class="value">@Html.TextBoxFor(x => x.ContactPhone)</div>
        <div class="value">@Html.ValidationMessageFor(x => x.ContactPhone)</div>
    </div>        <input type="submit" value="Submit" />
}

【问题讨论】:

    标签: validation asp.net-mvc-3 jquery-validate data-annotations


    【解决方案1】:

    默认行为正是您所描述的(只有在字段失去焦点或提交表单后才会出现错误)。因此,您的视图或控制器一定有问题。具体来说,即使在表单的第一个视图上,验证器也认为用户正在回发。表单的第一个视图应该是 GET 而不是 POST。如果您粘贴控制器代码,这可能有助于我们更好地诊断它。

    【讨论】:

    • 我目前对获取和发布使用相同的操作。你能举个例子说明验证器是如何混淆的吗?
    • 我仔细检查了,当页面首次加载时,RequestType 是控制器操作中的“GET”。当表单有效并提交时,然后是“POST”。
    【解决方案2】:

    您的意思是启用客户端验证?当然,这很容易。只是:

    1. 创建视图模型
    2. 装饰一下
    3. 创建控制器
    4. 创建视图
    5. 包括正确的 jquery 脚本

    所以让我们继续按照这些步骤操作。

    查看模型:

    public class ProductViewModel
    {
        [Required] // <-- you could use any data annotation attributes you like
        public string Name { get; set; }
    }
    

    控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new ProductViewModel();
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(ProductViewModel model)
        {
            return View(model);
        }
    }
    

    查看:

    @model ProductViewModel
    
    <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm())
    {
        @Html.LabelFor(x => x.Name)
        @Html.EditorFor(x => x.Name)
        @Html.ValidationMessageFor(x => x.Name)
        <input type="search" value="OK" />
    }
    

    现在将该字段留空,假设在web.config 中启用了客户端验证(当您使用默认的 Visual Studio 模板创建新的 ASP.NET MVC 3 项目时默认启用),客户端验证将触发:

    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
    </appSettings>
    

    如果您想处理自定义验证属性,您可以,但它可能是 little more painful。一旦您遇到现实世界的应用程序并意识到使用属性(数据注释)进行声明式验证的弱点,我强烈建议您查看FluentValidation.NET

    【讨论】:

    • 我目前正在使用数据注释来装饰我的模型以进行客户端/服务器端验证。我没有遇到任何值得一提的问题,但是由于我刚刚开始使用 MVC 应用程序,因此我对您发现的数据注释与您提到的 FluentValidation.NET 的弱点很感兴趣。跨度>
    • @Jed,让我们采用以下非常常见的情况:假设您有一些包含复选框的表单。根据是否选中复选框,您需要确保模型上的其他一些属性是必需的。如果未选中该复选框,则不需要这些属性。使用声明性数据注释属性这样做似乎有点难看。
    • @Jed - 在这种情况下 IValidatableObject 会比 DataAnnotation 属性更好吗?
    • @chief7 - 你指的是哪个场景?
    猜你喜欢
    • 2020-01-22
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多