我是ASP.NET MVC 5的新手。我喜欢学习在视图和视图模型之间构建双向绑定的正确方法。并利用客户端验证脚本。
这就是我所做的。
我创建了一个像这样的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>
答案 0 :(得分:1)
您的实施存在一些问题。
生成表单控件的所有HtmlHelper
方法都会生成双向模型绑定所需的正确name
和value
属性。您正在覆盖这些值,以便控件现在与您的模型没有任何关系。
在文本框之前,您还有Request.LocalFrom
属性的隐藏输入,因此当您提交时,只会隐藏隐藏输入的值(属性的原始值),并且编辑后的值文本框将被忽略。此外,由于隐藏的输入,为客户端验证生成的data-val-*
属性已应用于隐藏输入,而不是文本框。
不清楚为什么你需要2个视图模型,理想情况下你的DefaultViewPresenter
视图模型应该包含LocalFrom
和From
的属性,但是对于你当前的模型,你的视图需要是
@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: [] });
});
希望这有帮助!