如何使用ASP.NET MVC 5进行客户端验证?

时间:2016-09-14 20:34:10

标签: c# asp.net-mvc validation mvvm asp.net-mvc-5

我是ASP.NET MVC 5的新手。我喜欢学习在视图和视图模型之间构建双向绑定的正确方法。并利用客户端验证脚本。

这就是我所做的。

  1. 我加载了jQuery Library v 1.10.1
  2. 我正在加载Jquery-Validation
  3. 我已加载jQuery.Unobtrusive.Validation
  4. 我创建了一个像这样的ViewModel

    public class RequestFormViewModel
    {
        [Required]
        [Display(Name = "Day Of")]
        public DateTime LocalFrom { get; set; }
    
        [Required]
        [Display(Name = "Does not matter since this will be hidden and I use javascript to populate the value here when before the for is submitted")]
        public DateTime From { get; set; }
    
        public RequestFormViewModel()
        {
        }
    
        public RequestFormViewModel(DateTime localFrom, DateTime from)
        {
            this.LocalFrom = localFrom;
    
            this.From = from;
        }
    }
    

    这就是我创建视图的方式。请注意,我将演示者或业务层(即DefaultViewPresenter)传递给我的视图,而不是ViewModel。班级DefaultViewPresenter的属性已被列为Request。 (下面我将展示我的演示者的样子)

    @model Proj.Presenters.DefaultViewPresenter
    
    @using (Html.BeginForm("Index", "Track", FormMethod.Post, new { @class="form-inline", Id = "TrackActionForm" }))
    { 
        @Html.AntiForgeryToken()
        @Html.HiddenFor(m => m.Request.LocalFrom, new { Id = "TrackFrom", Name = "From" })                   
    
        <div class="input-group">
    
            @Html.TextBoxFor(m => m.Request.LocalFrom, new { Value = Model.Request.LocalFrom.ToString("MM/dd/yyyy"), @class = "form-control small", Id = "TrackLocalFrom", Name = "LocalFrom" })
            @Html.ValidationMessage("LocalFrom")
    
            <span class="input-group-btn">
                <button class="btn btn-info" type="button" id="TrackSubmit">View</button>
            </span>
    
        </div>
    
    }
    

    以下是我的演示者的样子

    public class DefaultViewPresenter
    {
        public RequestFormViewModel Request { get; set; }
        .... // some other propertied that I need for the view that are not related to my form
        ....
        ....
    }
    

    问题

    当我提交表单时,表单未提交!我没有得到任何错误。就像提交按钮在点击事件上有return;功能一样。

    如何让脚本正确验证,何时表单有效处理发布请求?

    我在这里缺少什么?我该如何纠正这个问题?

    运行我的应用程序后,这是razor正在生成的HTML标记

    <form novalidate="novalidate" id="TrackActionForm" action="/Track" class="form-inline" method="post">
        <input name="__RequestVerificationToken" value="thmJX-Mlj5WjM3e7WMbgtb8KiEf4vuUKGzon4zO18fHDDY3cWpm2M1Lks8HbZDxX2qz7UxpRsoYvz2njNwYS_D8zclTvu9pdsJlSO0ckNLQ1" type="hidden">
        <input id="TrackFrom" name="From" data-val="true" data-val-date="The field Day Of must be a date." data-val-required="The Day Of field is required." value="9/14/2016 12:00:00 AM" type="hidden">                    
        <div class="input-group">
    
            <input id="TrackLocalFrom" name="LocalFrom" value="09/14/2016" class="form-control small" type="text">
            <span class="field-validation-valid" data-valmsg-for="LocalFrom" data-valmsg-replace="true"></span>
    
            <span class="input-group-btn">
                <button class="btn btn-info" type="button" id="TrackSubmit">View</button>
            </span>
    
        </div>
    </form>
    

2 个答案:

答案 0 :(得分:1)

您的实施存在一些问题。

生成表单控件的所有HtmlHelper方法都会生成双向模型绑定所需的正确namevalue属性。您正在覆盖这些值,以便控件现在与您的模型没有任何关系。

在文本框之前,您还有Request.LocalFrom属性的隐藏输入,因此当您提交时,只会隐藏隐藏输入的值(属性的原始值),并且编辑后的值文本框将被忽略。此外,由于隐藏的输入,为客户端验证生成的data-val-*属性已应用于隐藏输入,而不是文本框。

不清楚为什么你需要2个视图模型,理想情况下你的DefaultViewPresenter视图模型应该包含LocalFromFrom的属性,但是对于你当前的模型,你的视图需要是

@model Proj.Presenters.DefaultViewPresenter

@using (Html.BeginForm("Index", "Track", FormMethod.Post, new { @class="form-inline", Id = "TrackActionForm" }))
{ 
    @Html.AntiForgeryToken() 
    <div class="input-group">          
        @Html.TextBoxFor(m => m.Request.LocalFrom, "{0:MM/dd/yyyy}", new { @class = "form-control small" })
        @Html.ValidationMessageFor(m => m.Request.LocalFrom)

        <span class="input-group-btn">
            <button class="btn btn-info" type="submit" id="TrackSubmit">View</button> // change to a submit button
        </span>
    </div>
}

请注意TextBoxFor()中的第二个参数是格式字符串,但如果您使用[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]适用于该属性,则可以省略该字符串。另请注意,HtmlHelper方法会根据属性名称生成id属性,通常没有理由覆盖它。

作为旁注,建议您在视图模型中使用nullable属性创建值类型属性[Required],以防止欠发布攻击(恶意用户发布备份和省略属性的名称/值对,在这种情况下,它将初始化为其默认值(DateTime.MinValue)。

[Required(ErrorMessage = "Please enter ...")]
[Display(Name = "Day Of")]
public DateTime? LocalFrom { get; set; }

答案 1 :(得分:0)

默认情况下,JQuery Validation会忽略客户端验证的隐藏字段。在视图的脚本块或_layout.cshtml中尝试以下操作:

$(document).ready(function(){ 
 $.validator.setDefaults({ ignore: [] });
});

希望这有帮助!