2013-03-13 91 views
24

是否有结合项视图的一个IList的图案。我似乎有问题与HttpPost。我知道菲尔哈克写了一篇很好的文章,但它是过时,他说,他们可能会与MVC 4模型绑定到一个List MVC 4

+0

请考虑添加更多细节,包括相关蚂蚁代码和链接到你的问题,使其更清晰。这里有一个很好的清单让你开始:http://tinyurl.com/so-list – mellamokb 2013-03-13 02:09:52

+0

将列表绑定到视图。什么不清楚这个? – Karthik 2013-03-13 02:17:49

+1

根据您的表单看起来有些变化。一些查看代码会有所帮助。 – AaronLS 2013-03-13 02:17:53

回答

46

修复这是我要做的事,如果我需要为每个项目显示的形式,以及各种属性的输入。真的取决于我想要做什么。

视图模型看起来是这样的:

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属性,那么在后置操作中将不可用,因为它不是表单中的字段。

注意的方式MVC模型结合的作品,它只会看连续的ID。因此,在有条件地隐藏项目的情况下做这样的事情会导致它在第五项后不绑定任何数据,因为一旦它在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)   
    } 
} 
+1

我使用mvc 5.1而不是'++ 1',我不得不这样做:'@ {++ i; },在'@foreach()'块内。 – Yustme 2014-03-03 15:58:25

+0

@Yustme也许,如果你有HTML标签,也许会出现这种情况,你需要'@ {}'将该上下文切换回C#代码。但好的提示无论哪种方式。 – AaronLS 2014-03-05 08:44:02

+5

声明“我”,然后使用foreach是非常丑陋的,特别是当我们有FOR LOOPS时。除非你确实需要,否则请不要使用特定的List实现。 – 2014-04-14 16:21:18

3

〜控制器

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。

+0

史蒂夫,感谢您的信息,这工作正常。我的问题,也许我没有解释是绑定一个动态列表。桑德森钉在这篇文章http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ – Karthik 2013-03-13 03:36:44

+0

@JT没关系,如果我在控制器中静态键入列表,或者从数据库或文件中获取它。列表来自哪里与模型绑定无关。 – 2013-03-13 03:38:11

+1

我的问题是与HttpPost。当视图中的对象列表发生更改时,值不会正确发布。这就是桑德森所说的,我正在使用他的方法。 MVC团队知道这一点,Sanderson的方法是我见过的最好的方法。我向所有人道歉,因为不清楚。 – Karthik 2013-03-13 04:02:10

6

一个干净的解决方案是创建一个通用类来处理列表中,这样你就不会需要创建一个不同的类中每个需要它的时候。

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... 
}