【问题标题】:How can I do client validation to form with ASP.NET MVC 5?如何使用 ASP.NET MVC 5 进行客户端验证以形成?
【发布时间】:2016-09-14 20:34:09
【问题描述】:

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

这是我所做的。

  1. 我正在加载 jQuery Library v 1.10.1
  2. 我正在加载Jquery-Validation
  3. 我加载了jQuery.Unobtrusive.Validation

我像这样创建了一个 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>

【问题讨论】:

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


    【解决方案1】:

    您的实施存在一些问题。

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

    你在文本框前还有一个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 属性,通常没有理由覆盖它。

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

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

    【讨论】:

    • 在这里感谢您的帮助。验证仍然对我不起作用。当我单击View 按钮时,没有任何反应。我希望表单能够提交。此外,现在LocalFrom 中的值显示日期和时间。我只想显示没有时间的日期。我将[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] 添加到我的ViewModel 中并删除了@Html.TextBoxFor 中的第二个参数是什么导致表单无法提交?
    • 啊。您的“查看”按钮就是这样 - 它是一个按钮。将其更改为 type="submit" 或使用 &lt;input class="btn btn-info" type="submit" value="View" /&gt;。然后,如果您从文本框中清除文本并单击“查看”,则会显示错误消息。
    • 另外,如果你使用DisplayFormatAttribute,那么你还需要ApplyInEditMode = true并使用EditorFor() 目前,坚持使用TextBoxFor()中的第二个参数来格式化值
    • Err 愚蠢的错误。谢谢你。现在表单提交了,但如果我没有在字段中输入值,它也会提交。没有进行验证。即使在添加ApplyInEditMode 之后,我仍然可以看到日期和时间,这就是我所拥有的@Html.TextBoxFor(m =&gt; m.Request.LocalFrom, new { @class = "form-control small", ApplyInEditMode = true })
    • 您是否删除了隐藏的输入?检查您生成的 html - 您现在应该看到 &lt;input name="Request.LocalFrom" id="Request_LocalFrom" 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" type="text" /&gt;
    【解决方案2】:

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

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

    希望这会有所帮助!

    【讨论】:

    • 它也忽略了文本输入,只是隐藏了
    • 您是说其他字段被忽略,而不仅仅是隐藏字段?
    • 这是正确的。 text 字段被忽略。根据 jQuery Validation,该属性应具有 required 属性。我在想 Razor 会自动为你添加它,因为我在 ViewModel 中将该属性标记为必需
    • 是在添加此脚本之前还是之后?当您将必需的属性添加到剃刀视图使用的模型中的属性时,框架会呈现必要的 html,以便在客户端正确验证该字段。你确定$.validator.setDefaults({ ignore: [] }); 正在被处决吗?
    • 我更新了我的问题,使其更清晰,并在修复了 HTML 代码的几个问题之后
    猜你喜欢
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多