在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