简体   繁体   English

模型绑定到列表MVC 4

[英]Model Binding to a List MVC 4

Is there a pattern to bind an IList of items to the view. 是否有将IList项绑定到视图的模式。 I seem to be having issues with the HttpPost. 我似乎遇到了HttpPost的问题。 I know Phil Haack wrote a nice article but it is dated and he said they might have a fix with MVC 4. 我知道菲尔哈克写了一篇很好的文章,但它已经过时了,他说他们可能会修复MVC 4。

This is how I do it if I need a form displayed for each item, and inputs for various properties. 如果我需要为每个项目显示一个表单,并为各种属性输入,我就是这样做的。 Really depends on what I'm trying to do though. 真的取决于我想要做的事情。

ViewModel looks like this: ViewModel看起来像这样:

public class MyViewModel
{
   public List<Person> Persons{get;set;}
}

View(with BeginForm of course): 查看(当然有BeginForm):

@model MyViewModel


@for( int i = 0; i < Model.Persons.Count(); ++i)
{
    @Html.HiddenFor(m => m.Persons[i].PersonId)
    @Html.EditorFor(m => m.Persons[i].FirstName) 
    @Html.EditorFor(m => m.Persons[i].LastName)         
}

Action: 行动:

[HttpPost]public ViewResult(MyViewModel vm)
{
...

Note that on post back only properties which had inputs available will have values. 请注意,在回发后,只有具有可用输入的属性将具有值。 Ie, if Person had a .SSN property, it would not be available in the post action because it wasn't a field in the form. 即,如果Person具有.SSN属性,则它不会在post操作中可用,因为它不是表单中的字段。

Note that the way MVC's model binding works, it will only look for consecutive ID's. 请注意,MVC的模型绑定的工作方式,它只会查找连续的ID。 So doing something like this where you conditionally hide an item will cause it to not bind any data after the 5th item, because once it encounters a gap in the IDs, it will stop binding. 因此,在有条件地隐藏项目的情况下执行此类操作将导致它在第5项之后不绑定任何数据,因为一旦遇到ID中的间隙,它将停止绑定。 Even if there were 10 people, you would only get the first 4 on the postback: 即使有10个人,你也只会获得回发中的前4个:

@for( int i = 0; i < Model.Persons.Count(); ++i)
{
    if(i != 4)//conditionally hide 5th item, 
    { //but BUG occurs on postback, all items after 5th will not be bound to the the list
      @Html.HiddenFor(m => m.Persons[i].PersonId)
      @Html.EditorFor(m => m.Persons[i].FirstName) 
      @Html.EditorFor(m => m.Persons[i].LastName)           
    }
}

A clean solution could be create a generic class to handle the list, so you don't need to create a different class each time you need it. 一个干净的解决方案可以创建一个通用类来处理列表,因此您不需要在每次需要时创建不同的类。

public class ListModel<T>
{
    public List<T> Items { get; set; }

    public ListModel(List<T> list) {
        Items = list;
    }
}

and when you return the View you just need to simply do: 当您返回视图时,您只需要执行以下操作:

List<customClass> ListOfCustomClass = new List<customClass>();
//Do as needed...
return View(new ListModel<customClass>(ListOfCustomClass));

then define the list in the model: 然后在模型中定义列表:

@model ListModel<customClass>

and ready to go: 准备好了:

@foreach(var element in Model.Items) {
  //do as needed...
}

~Controller 〜控制器

namespace ListBindingTest.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            List<String> tmp = new List<String>();
            tmp.Add("one");
            tmp.Add("two");
            tmp.Add("Three");
            return View(tmp);
        }

        [HttpPost]
        public ActionResult Send(IList<String> input)
        {
            return View(input);
        }    
    }
}

~ Strongly Typed Index View 〜强类型索引视图

@model IList<String>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
    <div>
    @using(Html.BeginForm("Send", "Home", "POST"))
    {
        @Html.EditorFor(x => x)
        <br />
        <input type="submit" value="Send" />
    }
    </div>
</body>
</html>

~ Strongly Typed Send View 〜强类型发送视图

@model IList<String>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Send</title>
</head>
<body>
    <div>
    @foreach(var element in @Model)
    {
        @element
        <br />
    }
    </div>
</body>
</html>

This is all that you had to do man, change his MyViewModel model to IList. 这就是你必须做的所有事情,将他的MyViewModel模型更改为IList。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM