0

ViewModel 클래스가있는 폼이 있습니다. 폼의 필드에 대해 [필수] 유효성 검사를 설정했습니다. 양식은 제출하는 순간에도 특정 필드에 설정된 ErrorMessage를 표시하는 순간에도 계속 제출됩니다.ASP Net MVC - ViewModel의 양식 유효성 검사

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에 추가 : 이미이 번들을 가져야한다

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

것은 당신이 사용하는 경우 기본 MVC 템플릿 : 당신의 _Layout보기 또는보기에서

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

을 그리고 렌더링 당신은 확인을 원하는 . 보기에 참조가 있는지 확인하십시오. Mozzila의 Firebug와 같은 웹 개발 도구를 사용하거나 Chrome의 F12 키를 눌러 js 파일이로드되었는지 확인할 수 있습니다. NET 탭에서로드 된 스크립트를 볼 수 있습니다.