【问题标题】:MVC Model data is not bindingMVC 模型数据未绑定
【发布时间】:2019-10-01 09:30:44
【问题描述】:

我创建了添加客户的表单。我用 Viewmodel 渲染了客户页面。查看Model类如下,

public class CustomerViewModel
{
    public IEnumerable<MemberShipType> MemberShipTypes { get; set; }
    public Customer Customers { get; set; }
}  

public class Customer
{
    [Display(Name ="Customer ID")]
    public int CustomerId { get; set; }

    [Required(ErrorMessage = "Please enter customer name")]
    [StringLength(255)]
    [Display(Name ="Customer Name")]
    public string CustomerName { get; set; }

    public MemberShipType MemberShipType { get; set; }

    [Required(ErrorMessage = "Please select membership type")]
    [Display(Name = "Membership Type")]
    public byte MembershipTypeId { get; set; }
}

public class MemberShipType
{
    [Display(Name ="Membership Id")]
    public byte Id { get; set; }
    [Required]
    [Display(Name = "Subscription Plan")]
    public string Name { get; set; }
}

添加该类后,我们创建了 Action 以使用单个模型类(不是 viewModel)保存客户表单数据

我使用 Viewmodel 创建了客户表单,以显示会员类型数据。

使用以下代码可以很好地呈现 UI。但是,我无法在 action 方法中获取模型数据。

如果我直接在动作数据中使用视图模型就可以了。问题需要将所有视图模型属性映射到特定模型。

每次映射模型属性都需要更多时间。

谁能知道如何直接使用实体框架添加方法和客户模型(不是视图模型)

@using (Html.BeginForm("Save", "Customer", FormMethod.Post))
{
    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(m => m.Customers.CustomerName, htmlAttributes: 
            new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(m => m.Customers.CustomerName, 
                new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(m => m.Customers.CustomerName, "", 
                new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.Customers.MembershipTypeId, htmlAttributes: 
             new { @class = "control-label col-md-2" })
            <div class="col-lg-10">

                @Html.DropDownListFor(m => m.Customers.MembershipTypeId,
                    new SelectList(Model.MemberShipTypes, "Id", "Name"), 
                    "Please Select", new {@class = "form-control"})

                @Html.ValidationMessageFor(m => m.Customers.MembershipTypeId, 
                    "", 
                    new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-lg-10 col-lg-offset-2">
                <input type="reset" value="Reset" class="btn btn-default" />
                <button type="submit" class="btn btn-primary">Save</button>    
            </div>
        </div>

    </div>
}

下面的动作模型总是返回null。

        [System.Web.Mvc.HttpPost]
        public ActionResult Save(Customer customer)
        {
            if (customer.CustomerId == 0)
            { 
              _context.Customer.Add(customer);
              _context.SaveChanges();
            }
        }

我得到一个客户模型为空。如果我通过 customerViewModel 数据来了。谁能知道如何直接获取模型类中的数据?

【问题讨论】:

    标签: c# model-view-controller asp.net-mvc-5


    【解决方案1】:

    由于您将视图绑定到 CustomerViewModel 的模型并且您正在使用 HTML 帮助程序 EditorFor(lambda 重载),因此您应该期望在您的 POST 中返回相同的模型。当您使用 LabelFor 和 EditorFor 时,自动命名可能会为您提供类似“Customers_CustomerName”的内容,因此它可以将您的视图模型重新组合在一起。

    一种解决方案是将保存方法上的预期模型更改为“CustomerViewModel”,然后使用 .Customer 属性获取数据。

    [System.Web.Mvc.HttpPost]
            public ActionResult Save(CustomerViewModel model)
            {
                if (model.Customer.CustomerId == 0)
                { 
                  _context.Customer.Add(model.Customer);
                  _context.SaveChanges();
                }
            }
    

    另一个选项是手动命名您的输入字段以直接反映“客户”模型的属性,它会在 POST 上将它们映射到您的“客户”模型中。例如,您只需使用 @Html.EditorFor("CustomerName", Model.Customers.CustomerName)

    而不是 @Html.LabelFor(m => m.Customers.CustomerName)
    <div class="form-group">
                @Html.LabelFor(m => m.Customers.CustomerName, htmlAttributes: 
                new { @class = "control-label col-md-2" })
                <div class="col-md-10">
     *********EDIT HERE      --> @Html.TextBox("CustomerName", Model.Customers.CustomerName
                    new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(m => m.Customers.CustomerName, "", 
                    new { @class = "text-danger" })
                </div>
            </div>
    

    【讨论】:

    • 它可以正常工作。毫无疑问。天气晴朗。假设如果我需要使用多个模型来呈现我的页面,那将是一个问题。例如,我的表单中有 10 多个下拉选项。如果我需要从各种表(不同的模型)中为这些下拉列表呈现数据,它将不起作用。这就是我创建视图模型的原因:)
    • 可以在此处找到有关绑定工作原理的更好答案:stackoverflow.com/questions/30416615/… 我说您的视图中需要与 post 操作中相同的模型是不正确的。但是您需要的是相同的命名约定,以便可以正确映射表单集合,而您在原始问题中没有。我不确定您标记为答案的重复名称问题是否是完整的问题,但我很高兴它现在对您有用!
    【解决方案2】:

    我得到了这个问题的解决方案。问题的原因是,我创建了同名的控制器和模型。所以,我在 Viewmodel 中用不同的别名更改了模型名称,如下所示,

    public class CustomerViewModel 
    { 
        public IEnumerable<MemberShipType> MemberShipTypes 
        { get; set; } 
        public ProductionCustomer productionCustomers 
        { get; set; }
    }  
    

    如果我们在控制器中使用模型对象来获取/发布,即使我们使用 ViewModel(多模型)渲染表单,它也会起作用。默认情况下,mvc 将识别要在表单中发布的模型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 2014-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      相关资源
      最近更新 更多