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選項卡中查看加載的腳本。