MVC3-将整个模型与动态数据从视图传递到控制器

时间:2012-07-10 20:49:35

标签: asp.net asp.net-mvc asp.net-mvc-3 model-binding

我有两个模型:OuterModel和InnerModel。 OuterModel和InnerModel之间分别存在一对多的关系。为了澄清我的问题,我的模型是IEnumerable< OuterModel>类型。我将随机数量的OuterModel传递给视图,用户为每个OuterModel创建任意数量的InnerModel。然后在提交时,我希望控制器接收OuterModel列表,以便可以将InnerModels添加到数据库中的预期外部模型。

我相信我的命名约定是正确的,可以使用MVC的内置模型绑定。这是看起来像:

OuterModel[i].InnerModel[j].Property

我的问题是,我真的不知道如何获得传递给控制器​​的OuterModel列表。这是我在视图中尝试过的内容:

    @model IEnumerable<OuterModel>

    @using (Html.BeginForm("Create", "Controller", new { OuterModels = Model }, FormMethod.Post))
    {
       //Code to create the InnerModels here
    }

以下是我在控制器中的内容:

    [HttpPost]
    public ActionResult Create(IEnumerable<OuterModel> OuterModels, FormCollection fc)
    {
       String[] keys = fc.AllKeys;
       if(ModelState.IsValid){
          //Add to db
       }
    }

Keys显示我的所有属性都遵循我之前指定的命名约定,但ModelState.IsValid返回false。它显示OuterModels的计数为0。

即使我在创建任何InnerModel之前告诉表单提交OuterModels = Model,你会认为在OuterModels中仍然会有数据传递给视图。我今天真的很累,所以我猜我正在看一个(或许多)小细节。有什么建议吗?

- 编辑 -

将OuterModel列表传递给控制器​​可能不是最好的方法。如果有人有更好的建议,请分享。

1 个答案:

答案 0 :(得分:1)

只要正确使用索引,这应该不是问题。我将如何设想表单名称。

模型[0]包含.foo

模型[0] .Inner [0]的.bar

模型[0] .Inner [1]的.bar

外部模型有一个名为foo和的属性 外部模型有一个名为inner的属性,它是内部对象的集合。内部对象有一个名为bar的属性。如果使用正确的索引呈现表单,则模型绑定应该起作用。如果表单字段是客户端生成的,那么事情会变得棘手。我建议回到服务器以操纵模型。还有一些额外的往返旅行,但你可以通过Ajax请求来制作它们。

以下是一个更加充实的例子中的更多细节。

public class InnerModel{
    public string Name{get; set;}
}

public class OuterModel{
   public List<InnerModel> InnerModels{get; set;}
   public string Name{get; set;}
}

以下是我想象的观点:

@model IEnumerable<OuterModel>

<ul>
  @{int i = 0;}
  @foreach(var item in Model){
     <li>
        Outer Name : @Html.TextBoxFor(m=>Model[i].Name)
        <br />
        @{int j = 0;}
        <ul>
            @foreach(var innerItem in Model[i].InnerModels){
               <li>Inner Name : @Html.TextBoxFor(m=> Model[i].InnerModels[j].Name)</li>
               j++;

            }
        </ul> 
        i++;
     </li>
  }
</ul>

如果它包含在一个表单中 - 并且控制器操作如下所示:

public ActionResult Action(List<OuterModel> model){
}

然后我会认为模型会正确填充。

我注意到你的表格..它看起来不对我......我不认为通过这样的外部模型会起作用 - 虽然坦率地说我可能是错的。

@using (Html.BeginForm("Create", "Controller", new { OuterModels = Model }, FormMethod.Post))
{
   //Code to create the InnerModels here
}

这是我为我上课所做的一个例子..这绝对有用..

public class Author
{
    public string Name { get; set; }
}

public class Book
{
    public string Name { get; set; }

    public List<Author> Authors { get; set; }
}

控制器:

public class BookController : Controller
{

    public static List<Book> _model = null;

    public List<Book> Model
    {
        get
        {
            if (_model == null)
            {
                _model = new List<Book>
                {
                    new Book{
                        Name = "Go Dog Go", 
                        Authors = new List<Author>{
                            new Author{Name = "Dr. Seuss"}
                        }},
                    new Book{
                        Name = "All the Presidents Men", 
                        Authors = new List<Author>{
                            new Author{Name = "Woodward"},
                            new Author{Name = "Bernstein"}
                        }},
                    new Book{
                        Name = "Pro ASP.NET MVC Framework", 
                        Authors = new List<Author>{
                            new Author{Name = "Sanderson"},
                            new Author{Name = "Stewart"},
                            new Author {Name = "Freeman"}
                        }}
                };
            }
            return _model;
        }
    }

    public ActionResult Index()
    {
        return View(Model);
    }

    public ActionResult Edit()
    {
        return View(Model);
    }

    [HttpPost]
    public ActionResult Edit(List<Book> books)
    {
        _model = books;
        return RedirectToAction("Index");
        //return View(books);
    }

}

和查看:

@model List<AmazonWeb.Models.Book>
@{
    ViewBag.Title = "Index";
}

<div class="content">

@Html.ActionLink("Index", "Index")

@using (Html.BeginForm())
{
  <input type="submit" value="save" />
<ul class="book-list">

@for (var i = 0; i < Model.Count; i++ )
{
    <li>
        <label>Book Name</label> : @Html.TextBoxFor(m => Model[i].Name)
        <ul>
            @for (var j = 0; j < Model[i].Authors.Count; j++ )
            {
                <li><label>Author Name</label> : @Html.TextBoxFor(m => Model[i].Authors[j].Name)</li>
            }
        </ul>
    </li>
}
</ul>
    <input type="submit" value="save" />
}
</div>