在ViewModel上进行表单验证
我有一个窗体,它有一个ViewModel类。 我已经在窗体的字段上设置了[必需的]验证。 表单仍然提交,即使它提交 - 在提交之前 - 显示在特定字段上设置的ErrorMessage。
StockReceipt模型本身没有验证,但只有ViewModel。 我在这里看到了这个问题,并得知验证模型是可选的。
我想知道为什么当输入无效时表单仍然提交?
这是我的View和ViewModel代码:
视图:
@using (Html.BeginForm("SaveSettings", "StockReceipt", FormMethod.Post,
new { id = "StockReceiptForm", enctype = "multipart/form-data" }))
{
<fieldset>
<div>
@* @Html.ValidationSummary(false)*@
<legend>Stock-Receipt Details</legend>
@*@if (User.IsInRole(Constants.Super))
{*@
<div style="display: none;">
Delivery Note Ref
</div>
<div style="display: none;">
@Html.TextBoxFor(model => model.StockReceiptID, new { @Class = "k-textbox" })
</div>
<div class="editor-label">
Supplier
</div>
<div class="editor-field">
@Html.Kendo().DropDownListFor(model => model.SupplierID).BindTo(Model.SuppliersList).DataTextField("Name").DataValueField("SupplierID").OptionLabel("Select")
@Html.ValidationMessageFor(model => model.SupplierID)
</div>
<div class="editor-label">
Material
</div>
<div class="editor-field">
@Html.Kendo().DropDownListFor(model => model.MaterialID).BindTo(Model.MaterialsList).DataTextField("Name").DataValueField("MaterialID").OptionLabel("Select")
@Html.ValidationMessageFor(model => model.MaterialID)
</div>
<div class="editor-label">
Qty
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Quantity, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.Quantity)
</div>
<div class="editor-label">
Of which reserved
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.QuantityReserved, new { @Class = "k-textbox" })
</div>
<div class="editor-label">
Units
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.NumberOfUnits, new { @Class = "k-textbox" })
@(Html.Kendo().DropDownListFor(model => model.StockUnitsEnum).Name("StockUnitsEnum")
.BindTo(Enum.GetValues(typeof(StockUnitsEnum))
.Cast<StockUnitsEnum>()
.Select(p => new SelectListItem
{
Text = p.ToString(),
Value = ((int)p).ToString(CultureInfo.InvariantCulture)
})
.ToList())
)
@Html.ValidationMessageFor(model => model.NumberOfUnits)
</div>
<div class="editor-label">
Batch Reference:
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.BatchReference, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.BatchReference)
</div>
<div class="editor-label">
Slab Width
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.SlabWidth, new { @Class = "k-textbox" }) x @Html.TextBoxFor(model => model.SlabHeight, new { @Class = "k-textbox" })
</div>
<div class="editor-label">
Include Transport:
</div>
<div class="editor-field">
@Html.CheckBoxFor(model => model.IncludeTransport)
</div>
<div class="editor-label">
Notes
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Notes, new { @Class = "k-textbox" })
</div>
<div class="clear">
Totals
</div>
<div class="editor-label">
Unit Cost
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.UnitCost, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.UnitCost)
</div>
<div class="editor-label">
Units
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.NumberOfUnits, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.NumberOfUnits)
</div>
<div class="editor-label">
Slab Cost
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.SlabCost, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.SlabCost)
</div>
<div class="editor-label">
Location
</div>
<div class="editor-field">
@Html.Kendo().DropDownListFor(model => model.LocationID).BindTo(Model.LocationsList).DataTextField("Name").DataValueField("LocationID").OptionLabel("Select")
</div>
<div class="editor-label">
Purchase-Order Ref.
</div>
<div class="editor-field">
@Html.Kendo().DropDownListFor(model => model.PurchaseOrderID).BindTo(Model.PurchaseOrdersList).DataTextField("PONumber").DataValueField("PurchaseOrderID").OptionLabel("Select")
@Html.ValidationMessageFor(model => model.PurchaseOrdersList)
</div>
<div class="editor-label">
Invoice Ref.
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.InvoicNo, new { @Class = "k-textbox" })
@Html.ValidationMessageFor(model => model.InvoicNo)
</div>
<br />
<div class="editor-label">
</div>
<div class="editor-field">
<input type="submit" value="Save" class="k-button" />
</div>
</div>
</fieldset>
}
视图模型:
public class StockReceiptViewModel
{
public int StockReceiptID { get; set; }
[Required(ErrorMessage = "Required")]
public int SupplierID { get; set; }
[Required(ErrorMessage = "Required")]
public int MaterialID { get; set; }
[Required(ErrorMessage = "Required")]
public DateTime? ReceiptDate { get; set; }
[Required(ErrorMessage = "Required")]
public int Quantity { get; set; }
public int? QuantityReserved { get; set; }
[Required(ErrorMessage = "Required")]
public decimal? SlabWidth { get; set; }
[Required(ErrorMessage = "Required")]
public decimal? SlabHeight { get; set; }
[Required(ErrorMessage = "Required")]
public int SizeUnits { get; set; }
[Required(ErrorMessage = "Required")]
public StockUnitsEnum StockUnitsEnum
{
get {return (StockUnitsEnum)SizeUnits;}
set {SizeUnits = (int)value;}
}
[Required(ErrorMessage = "Required")]
public string BatchReference { get; set; }
[Required(ErrorMessage = "Required")]
[DataType(DataType.Currency)]
public decimal? UnitCost { get; set; }
[Required(ErrorMessage = "Required")]
public int? NumberOfUnits { get; set; }
[Required(ErrorMessage = "Required.")]
public int PurchaseOrderID { get; set; }
[Required(ErrorMessage = "Required")]
public string InvoicNo { get; set; }
[Required(ErrorMessage = "Required")]
public decimal SlabCost { get; set; }
public bool IncludeTransport { get; set; }
[Required(ErrorMessage = "Required.")]
public int LocationID { get; set; }
public int? EnteredBy { get; set; }
public DateTime OnSystemFrom { get; set; }
public string Notes { get; set; }
public List<SupplierViewModel> SuppliersList { get; set; }
public List<MaterialViewModel> MaterialsList { get; set; }
public List<LocationsViewModel> LocationsList { get; set; }
public List<PurchaseOrderViewModel> PurchaseOrdersList { get; set; }
public int LastModifiedBy { get; set; }
public DateTime LastModifiedDate { get; set; }
public int LiveQuantity { get; set; }
}
Controller方法也具有ModelState.Isvalid检查。
如果可以的话请帮忙。
非常感谢。
您需要将jquery.unobtrusive和jquery.validate文件添加到您的视图。 将此添加到您的BundleConfig.cs中:
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
然后在你的_Layout视图或视图中渲染它,你需要验证:
@Scripts.Render("~/bundles/jqueryval")
如果你正在使用默认的MVC模板,你应该已经有了这个包。 只要确保你在视图中有参考。 您可以使用Mozzila中的Firebug等Web开发工具加载js文件,或者在Chrome中按F12键,然后在NET选项卡中查看加载的脚本。
我已经通过确保提交表单的方法解决了这个问题,如果ModelState.IsValid为false,则返回viewmodel到页面(视图)。
这提供了返回的viewModel实际上与提交的相同:
[HttpPost]
public ActionResult SaveSettings(StockReceiptViewModel stockReceiptVm)
{
try
{
if (ModelState.IsValid)
{
var stockReceipt = new StockReceipt();
if (stockReceiptVm.StockReceiptID != 0)
{
MapViewModelToModel(stockReceiptVm, stockReceipt);
stockReceipt.LastModifiedBy = UserHelper.GetCurrentUserIDByEmail();
stockReceipt.LastModifiedDate = DateTime.Now;
//update
_stockReceiptRepository.UpdateStockReceipt(stockReceipt, stockReceiptVm.StockReceiptID);
}
else
{
MapViewModelToModel(stockReceiptVm, stockReceipt);
stockReceipt.EnteredBy = UserHelper.GetCurrentUserIDByEmail();
stockReceipt.OnSystemFrom = Utilities.RemoveTimeFromDate(DateTime.Now);
//save new
_stockReceiptRepository.InsertStockReceipt(stockReceipt);
}
return RedirectToAction("Index", "StockReceiptsGrid");
}
SetupViewDropdownLists(stockReceiptVm);
return View("Index", stockReceiptVm);
}
catch (Exception exc)
{
ErrorHelper.WriteToEventLog(exc);
return RedirectToAction("Index", "Error");
}
}
链接地址: http://www.djcxy.com/p/56609.html
上一篇: Forms Validation on the ViewModel
下一篇: DropDownListFor Unobtrusive Validation Required Not getting correct attributes