ITKeyword,专注技术干货聚合推荐

注册 | 登录

解决asp.net mvc - ASP Net MVC - Forms Validation on the ViewModel

itPublisher 分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:ASP.NET MVC (一)

从零开始学习ASP.NET MVC:开天辟地入门篇(一) 2009-2-27 20:11:26 已被阅读:1151 发表评论 一.摘要 和自身水平有关, 我总喜欢写入门级别的文章.比如虽然做项目

I have a form which has a ViewModel class underlaying it. I have set the [Required] validation on fields of the form. The form still submits even though it does for a moment - before it submits - displays the ErrorMessage set on particular fields.

There is no validation on the StockReceipt model itself, but only the ViewModel. I looked at this question here and learnt that validating the model is optional.

I wonder why the form still submits when there are invalid input?

Here is my View and ViewModel code:

View:

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

ViewModel:

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

}

The Controller method has the ModelState.Isvalid check as well.

Please help if you can.

Many thanks.

推荐:ASP.NET MVC MESS

  ASP.NET MVC Html.Action() http://www.2cto.com/kf/201207/143417.html ASP.NET MVC Html.TextBox 与 Html.TextBoxFor 区别 For支持强类型(model的类型),内部

asp.net-mvc asp.net-mvc-3 validation asp.net-mvc-4 viewmodel
|
  this question
edited Feb 24 '14 at 13:01 user1987392 2,065 3 20 42 asked Feb 24 '14 at 12:48 t_plusplus 1,700 2 23 40      did you add jquery.validate.unobtrusive.js in your view? –  freshbm Feb 24 '14 at 12:55      @freshbm yes it is added in the BundleConfig on App_Start, as shown in the Question update now. –  t_plusplus Feb 24 '14 at 13:00

 | 

2 Answers
2

You need to add jquery.unobtrusive and jquery.validate files to your views. Add this to your BundleConfig.cs:

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

And then render it on your _Layout View or in View you want validation:

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

If you are using default MVC template you should already have this bundle. Just make sure you have reference in your Views. You can check if your js files are loaded by using some web development tools like Firebug in Mozzila or press F12 in Chrome, and in NET tab you can see loaded scripts.


|
  this answer
answered Feb 24 '14 at 13:14 freshbm 3,945 2 24 53

 |  解决方法

I have solved this problem by making sure that the method to where this form is submitting, is returning the viewmodel to the page (view) if ModelState.IsValid is false.

This is provided that the viewModel being returned is actually the same as the submitted one:

   [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");
        }
    }

|
  this answer
answered Feb 25 '14 at 17:11 t_plusplus 1,700 2 23 40

 | 

推荐:ASP.NET MVC随想

从ASP.NET Web Form到ASP.NET MVC,我们感到既熟悉又陌生。它是ASP.NET Web Form的一个增强,一个替代,还是一个替补?我们做Web开发两者都需要了解掌握吗……  


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。