【问题标题】:Binding arrays with missing elements in asp.net mvc在asp.net mvc中绑定缺少元素的数组
【发布时间】:2010-08-25 10:40:08
【问题描述】:

我正在尝试将动态元素数组绑定到 html 中可能缺少索引的视图模型

例如使用视图模型

class FooViewModel
{
   public List<BarViewModel> Bars { get; set; }
}

class BarViewModel
{
   public string Something { get; set; }
}

和 html

<input type="text" name="Bars[1].Something" value="a" />
<input type="text" name="Bars[3].Something" value="b" />
<input type="text" name="Bars[6].Something" value="c" />

目前,bars 将只是空值。我怎样才能让模型活页夹忽略任何缺失的元素?即上面将绑定到:

FooViewModel
{
     Bars
     {
            BarViewModel { Something = "a" },
            BarViewModel { Something = "b" },
            BarViewModel { Something = "c" }
     }
}

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-2


    【解决方案1】:

    添加 .Index 作为您的第一个隐藏输入,以处理乱序元素,如 Phil Haacked blog 帖子中所述:

    <input type="text" name="Bars.Index" value="" />
    <input type="text" name="Bars[1].Something" value="a" />
    <input type="text" name="Bars[3].Something" value="b" />
    <input type="text" name="Bars[6].Something" value="c" />
    

    【讨论】:

    • 非常接近,但是这个网址中接受的答案有更完整的解决方案:stackoverflow.com/questions/8598214/…
    • @Levitikon - 您的链接中接受的解决方案是矫枉过正。您不需要为每个项目指定 .Index。我已经多次使用上述方法,而不需要链接中描述的额外隐藏输入。另外,Phil Haack 是 ASP.NET MVC 开发团队的一员,所以我很确定他在博客中写的内容是正确的选择。
    • @amurra 在 Haack 文章中他说要为每个字段使用单独的隐藏输入,因此看起来很有必要。
    • 我可以确认,在 MVC 5.2.3 中,每个字段都需要隐藏输入,并且值必须是正确的索引。
    【解决方案2】:

    一种可能的解决方法是将 ViewModel 和集合实例化为正确的大小(假设它是已知的),然后使用 TryUpdateModel 对其进行更新...类似于:

        [HttpPost]
        public ActionResult SomePostBack(FormCollection form)
        {
            // you could either look in the formcollection to get this, or retrieve it from the users' settings etc.
            int collectionSize = 6; 
    
            FooViewModel bars = new FooViewModel();
            bars.Bars = new List<BarViewModel>(collectionSize);
            TryUpdateModel(bars, form.ToValueProvider());
    
            return View(bars);
        }H
    

    【讨论】:

      【解决方案3】:

      MVC 能够自己填充列表。

      public ActionResult Index(FooViewModel model)
      {
         ...
      

      所以无论缺少什么,mvc 都会创建新的List&lt;BarViewModel&gt; 和 对于每个找到的索引 - [1]、[3]、[6],它将创建新的 BarViewModel 并将其添加到列表中。因此,您将获得带有填充 Bars 的 FooViewModel。

      【讨论】:

      • 是和不是。当序列中存在间隙时,MVC 似乎停止构建数组。
      【解决方案4】:

      我什至不知道那有效!

      考虑到这一点,id 做了类似的事情:

      <input type="text" name="Bars.Something" value="a" />
      <input type="hidden" name="Bars.Something" value="" />
      <input type="text" name="Bars.Something" value="b" />
      <input type="hidden" name="Bars.Something" value="" />
      <input type="hidden" name="Bars.Something" value="" />
      <input type="text" name="Bars.Something" value="c" />
      

      希望能发帖

      a,,b,,,c
      

      但我怀疑它会以与您描述的方式相同的方式绑定

      您可能会编写一个自定义模型绑定器来查找最大索引,创建一个该大小的列表,然后将元素放在正确的位置。

      说了这么多,等别人发布一个非常简单的属性,你可以把它放在你的属性上,让它正常工作;D

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多