模型绑定到列表MVC 4

Kar*_*hik 29 c# asp.net-mvc-4

是否有将IList项绑定到视图的模式.我似乎遇到了HttpPost的问题.我知道菲尔哈克写了一篇很好的文章,但它已经过时了,他说他们可能会修复MVC 4.

Aar*_*nLS 54

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

ViewModel看起来像这样:

public class MyViewModel
{
   public List<Person> Persons{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

查看(当然有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)         
}
Run Code Online (Sandbox Code Playgroud)

行动:

[HttpPost]public ViewResult(MyViewModel vm)
{
...
Run Code Online (Sandbox Code Playgroud)

请注意,在回发后,只有具有可用输入的属性将具有值.即,如果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)           
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 声明"我"然后使用foreach是非常难看的,特别是当我们有FOR LOOPS时.除非您确实需要,否则请不要使用特定的List实现. (5认同)

小智 9

一个干净的解决方案可以创建一个通用类来处理列表,因此您不需要在每次需要时创建不同的类.

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

    public ListModel(List<T> list) {
        Items = list;
    }
}
Run Code Online (Sandbox Code Playgroud)

当您返回视图时,您只需要执行以下操作:

List<customClass> ListOfCustomClass = new List<customClass>();
//Do as needed...
return View(new ListModel<customClass>(ListOfCustomClass));
Run Code Online (Sandbox Code Playgroud)

然后在模型中定义列表:

@model ListModel<customClass>
Run Code Online (Sandbox Code Playgroud)

准备好了:

@foreach(var element in Model.Items) {
  //do as needed...
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*a D 5

~控制器

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);
        }    
    }
}
Run Code Online (Sandbox Code Playgroud)

~ 强类型索引视图

@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>
Run Code Online (Sandbox Code Playgroud)

~ 强类型发送视图

@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>
Run Code Online (Sandbox Code Playgroud)

这就是您要做的全部工作,将他的 MyViewModel 模型更改为 IList。