模型绑定到列表MVC 4

本文关键字:MVC 列表 绑定 模型 | 更新日期: 2023-09-27 18:03:42

是否存在将项目列表绑定到视图的模式?我似乎有问题的HttpPost。我知道Phil Haack写了一篇很好的文章,但是已经过时了,他说他们可能会修复MVC 4。

模型绑定到列表MVC 4

如果我需要为每个项目显示一个表单,并为各种属性输入,我就是这样做的。但这取决于我想做什么。

ViewModel看起来像这样:

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

视图(当然包括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)         
}

行动:

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

注意,在回发时,只有具有可用输入的属性才会有值。例如,如果Person有。ssn属性,则在post操作中不可用,因为它不是表单中的字段。

注意MVC的模型绑定的工作方式,它只会寻找连续的ID。因此,在有条件地隐藏项目时,这样做将导致它在第5个项目之后不绑定任何数据,因为一旦它遇到id中的空白,它将停止绑定。即使有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)           
    }
}

一个干净的解决方案是创建一个泛型类来处理列表,这样您就不需要每次需要时都创建一个不同的类。

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

当你返回视图时你只需要简单地执行:

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

然后在模型中定义列表:

@model ListModel<customClass>

准备就绪:

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

~

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

~强类型发送视图

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

这就是你所要做的,把他的MyViewModel模型改成IList。