【问题标题】:MVC 4 Ajax.BeginForm POST does not bind to model in conrollerMVC 4 Ajax.BeginForm POST 未绑定到控制器中的模型
【发布时间】:2014-02-07 02:27:59
【问题描述】:

很抱歉这里的代码量很大,但这是解释正在发生的事情的最佳方式。

我在 MVC 4 部分视图中给出了这段代码:

  <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
  @using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
    {                               
        foreach (var d in Model.DataItemsWithLabels)
        {                                    
            @Html.LabelFor(m => d.DataName)
            @Html.TextBoxFor(m => d.DataValue);             
        }

        <input type="submit" value="Save" />
    }

而我的控制器动作如下:

 public ActionResult TestPost(CmaPartialModel model)
 {         
        return PartialView("Transaction", model);
 }

在我的模型中,我有一些代码填充对象列表(仅当它们为空时),这些对象定义为:

 public List<DataItemWithLabel> DataItemsWithLabels { get; set; }      

    public class DataItemWithLabel
    {
        public string DisplayName { get; set; }

        public string DataName { get; set; }

        [Required]
        public string DataValue { get; set; }
    }  

我也有正确的 web.config 条目:

我在这里和其他地方阅读了大量帖子,但没有成功。

代码确实发布到TestPost 方法,但模型始终为空。谁能告诉我为什么会这样?

【问题讨论】:

    标签: ajax asp.net-mvc asp.net-mvc-4 asp.net-ajax


    【解决方案1】:

    你需要修改你的 Post 方法如下

    public ActionResult TestPost(IEnumerable<DataItemWithLabel> model)
     {         
            return PartialView("Transaction", model);
     }
    

    因为您将 DataItemWithLabel 模型的集合传递给您的控制器。

    【讨论】:

    • 谢谢 - 这是有道理的 - 虽然我的 DataItemWithLabel 在模型 CmaPartialModel 中,所以返回 null。
    【解决方案2】:

    你总是得到null 值的原因是模型绑定器不知道如何绑定对象列表。见下例:

    public class CmaPartialModel 
    {
        public List<DataItemWithLabel> DataItemsWithLabels { get; set; } 
    }
    

    然后在你的视图中使用它:

    @model  CmaPartialModel 
    
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
    @using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
    {
        for(var i = 0; i < Model.DataItemsWithLabels.Count; i++)
         {
            @Html.LabelFor(m => m.DataItemsWithLabels[i].DataName)
            @Html.TextBoxFor(m => m.DataItemsWithLabels[i].DataValue)
         }
        <input type="submit" value="Save" />
    }
    

    最后,你的action方法应该如下:

     public ActionResult TestPost(CmaPartialModel model)
     {         
            return PartialView("Transaction", model);
     }
    

    更新

    您也可以在您的视图中使用foreach,如下所示:

    foreach (var item in Model.DataItemsWithLabels.Select((value, i) => new { i, value }))
    {
       @Html.LabelFor(m => m.DataItemsWithLabels[@item.i].DataName)
       @Html.TextBoxFor(m => m.DataItemsWithLabels[@item.i].DataValue);   
    }
    

    【讨论】:

    • 感谢 Lin - 我的 ViewModel 中已经有一个与该列表完全相同的列表 - 我只是将其称为 CmaPartialModel。您的解决方案几乎可以工作,但我能看到的唯一区别是 for 循环而不是 foreach - 为什么 foreach 有问题或者我错过了什么?
    • 嗨@davy,问题不在于使用 for 或 foreach 循环所有 DataItemWithLabel 模型,您可以使用其中任何一个。问题是当您使用 foreach 循环所有项目时,模型绑定器不知道如何将数据绑定到它。因此,您需要创建诸如索引之类的东西来标记所有项目,然后模型绑定器为所有项目列表绑定数据。我更新了关于如何使用 foreach 执行此操作的答案,请看一下。
    【解决方案3】:
    I think below code will help you.
    

    查看

    @model MvcApplication1.Models.CmaPartialModel   
    @{
    ViewBag.Title = "Index";
    }
    <h2>Index</h2>
    @using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" }))
     {
       if (Model != null)
        {
        foreach (var d in Model.DataItemsWithLabels)
        {                                    
            @Html.LabelFor(m => d.DataName)
            @Html.TextBoxFor(m => d.DataValue);
        }
       }
      <input type="submit" value="Save" />
    }
    

    型号

    public class CmaPartialModel
    {
        public List<DataItemWithLabel> DataItemsWithLabels { get; set; }
    
        public class DataItemWithLabel
        {
            public string DisplayName { get; set; }
    
            public string DataName { get; set; }
    
            public string DataValue { get; set; }
        }  
    }
    

    控制器

    public ActionResult Index()
        {
            return View();
        }
        public ActionResult TestPost(CmaPartialModel model)
        {
            List<CmaPartialModel.DataItemWithLabel> parts = new      List<CmaPartialModel.DataItemWithLabel>();
            parts.Add(new CmaPartialModel.DataItemWithLabel() {DisplayName = "abc",DataName = "cbv",DataValue = "343"});
            parts.Add(new CmaPartialModel.DataItemWithLabel() { DisplayName = "sfda", DataName = "xzfdsf", DataValue = "234" });
            model.DataItemsWithLabels = parts;
            return PartialView("Index", model);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 2012-05-25
      相关资源
      最近更新 更多