0

我有一个窗体,它有一个ViewModel类下面。我已经在窗体的字段上设置了[必需的]验证。表单仍然提交,即使它提交 - 在提交之前 - 显示在特定字段上设置的ErrorMessage。ASP网MVC - 在视图模型上的窗体验证

StockReceipt模型本身没有验证,但只有ViewModel。我看了这个问题here,并得知验证模型是可选的。

我不知道为什么表单在输入无效时仍然提交?

这里是我的看法和视图模型代码:

查看:

@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; } 

} 

的控制方法具有ModelState.Isvalid检查为好。

如果可以,请帮助。

非常感谢。

+0

你在你的视图中添加jquery.validate.unobtrusive.js? – freshbm

+0

@freshbm是它被添加到App_Start的BundleConfig中,如现在的问题更新所示。 –

回答

1

我已经解决了这个问题,通过确保提交表单的方法在ModelState.IsValid为false时将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"); 
     } 
    } 
2

您需要将jquery.unobtrusive和jquery.validate文件添加到您的视图。添加到您的BundleConfig.cs:您_layout查看或查看

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
         "~/Scripts/jquery.unobtrusive*", 
         "~/Scripts/jquery.validate*")); 

然后渲染它,你想验证:

@Scripts.Render("~/bundles/jqueryval") 

如果使用默认MVC模板,你应该已经有这个包。只要确保你在视图中有参考。您可以使用Mozzila中的Firebug等Web开发工具加载js文件,或者在Chrome中按F12键,然后在NET选项卡中查看加载的脚本。