C# 模型绑定到列表 MVC 4
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15375800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Model Binding to a List MVC 4
提问by Karthik
Is there a pattern to bind an IList of items to the view. I seem to be having issues with the HttpPost. I know Phil Haack wrote a nice article but it is dated and he said they might have a fix with MVC 4.
是否有将项目的 IList 绑定到视图的模式。我似乎对 HttpPost 有问题。我知道 Phil Haack 写了一篇不错的文章,但它已经过时了,他说他们可能会修复 MVC 4。
采纳答案by AaronLS
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:
视图模型看起来像这样:
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. I.e., 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. 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. Even if there were 10 people, you would only get the first 4 on the postback:
请注意 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)
}
}
回答by Steve's a D
~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。
回答by Javi
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:
当您返回 View 时,您只需要简单地执行以下操作:
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...
}