Asp:net MVC 3:@ Html.Editor在模板中对我的模型进行子集合?

J4N*_*J4N 21 .net c# asp.net-mvc partial-views asp.net-mvc-3

我已经被困了很长时间来编辑我的模型的子集合,模型的集合变为空.

我终于找到了一个解决方案,但我发现它有点脏:

首先是我的测试数据:

模型对象:

    public class ContainerObject
    {
        public String Title { get; set; }
        public List<ContainedObject> ObjectList { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

子集合对象:

public class ContainedObject
{
    public int Id { get; set; }
    public String Text { get; set; }
    public Boolean IsSelected { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

生成对象的控制器方法

    public ActionResult TestForm()
    {
        return View(new ContainerObject()
        {
            Title = "This is a sample title",
            ObjectList = new List<ContainedObject>()
                {
                    new ContainedObject(){Id=1, IsSelected = true, Text="ObjectOne"},
                    new ContainedObject(){Id=2, IsSelected = false, Text="ObjectTwo"},
                    new ContainedObject(){Id=3, IsSelected = true, Text="ObjectThree"},
                    new ContainedObject(){Id=4, IsSelected = false, Text="ObjectFour"},
                }
        });
    }
Run Code Online (Sandbox Code Playgroud)

接收编辑对象的控制器

    [HttpPost]
    public ActionResult TestFormResult(ContainerObject filledObject)
    {
        return View();
    }
Run Code Online (Sandbox Code Playgroud)

风景

@model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
}
@using (Html.BeginForm("TestFormResult","Home", FormMethod.Post)){
    @Html.EditorFor(x => x.Title)
    Html.RenderPartial("ContainedObject", Model.ObjectList);
    <input type="submit"  value="Submit"/>
}
Run Code Online (Sandbox Code Playgroud)

局部视图(ContainedObject.cshtml)

@model IEnumerable<WebTestApplication.Models.ContainedObject>
@{
    ViewBag.Title = "ContainedObject";
    int i = 0;
}
@foreach (WebTestApplication.Models.ContainedObject currentObject in Model)
{ 
    <br />
    @Html.Label(currentObject.Text);
    @Html.CheckBox("ObjectList[" + i + "].IsSelected", currentObject.IsSelected);                                                                                                     
    @Html.Hidden("ObjectList[" + i + "].Id", currentObject.Id);                                                                                                
    @Html.Hidden("ObjectList[" + i + "].Text", currentObject.Text);
    i++;
}
Run Code Online (Sandbox Code Playgroud)

这实际上是有效的,但我有一个问题:

  • 我自己生成名称并指定容器对象的属性

我尝试使用Html.EditorFor而不是Html.RenderPartial在视图中,问题是它生成了我的名字"ObjectList.[0] .Id"(在属性名称和访问者之间有一个额外的.).

我还尝试在局部视图中仅使用@ Html.EditorFor,但它创建了具有对象名称的变量.

如果我不使用任何模板,它的工作原理如下:

    @model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
}
@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post))
{
    @Html.EditorFor(x => x.Title)
    for (int i = 0; i < Model.ObjectList.Count; i++)
    {
        <br />
        @Html.Label(Model.ObjectList[i].Text);
        @Html.CheckBoxFor(m => Model.ObjectList[i].IsSelected);
        @Html.HiddenFor(m => Model.ObjectList[i].Id);
        @Html.HiddenFor(m => Model.ObjectList[i].Text);
    }

    <br /><input type="submit"  value="Submit"/>
}
Run Code Online (Sandbox Code Playgroud)

但这里它是一个简单的模板,但在我的实际情况中,我会有更多的数据,这将被多次重复使用.那么我最好的选择是什么?

Den*_*vin 38

您可以通过引入EditorTemplate来简化代码.方法如下:

  • 除了我们用EditorFor替换RenderPartial之外,主视图几乎保持不变:

TestForm.cshtml

@model WebTestApplication.Models.ContainerObject

@{
    ViewBag.Title = "TestForm";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) {
    @Html.EditorFor(m => m.Title)
    @Html.EditorFor(m => m.ObjectList);

    <input type="submit" value="Submit" />
}
Run Code Online (Sandbox Code Playgroud)
  • 然后在Views/Home下创建一个名为EditorTemplates的文件夹(假设您的控制器是Home):

在此输入图像描述

  • 并为ContainedObject添加以下模板:

ContainedObject.cshtml

@model WebTestApplication.Models.ContainedObject

<p>
    @Html.DisplayFor(m => m.Text)
    @Html.CheckBoxFor(m => m.IsSelected)
    @Html.HiddenFor(m => m.Id)
    @Html.HiddenFor(m => m.Text)
</p>
Run Code Online (Sandbox Code Playgroud)

编辑器将自动遍历对象列表,为每个对象呈现视图.希望能帮助到你.


Tom*_*ken 7

我找到了这个线程,同时寻找其他相关的东西.Denis有正确的答案,但我想我会添加一些语法以防其他人遇到这个:

如果您有一个名为"SomeTemplate.cshtml"的编辑器模板,则可以在视图中将其用作Item列表,如下所示:

@for (var i = 0; i < Model.ObjectList.Count(); i++)
{
    @Html.EditorFor(m => m.ObjectList[i], "SomeTemplate")
}
Run Code Online (Sandbox Code Playgroud)

然后在您的编辑器模板中:

@model WebTestApplication.Models.ContainedObject

<br />
@Html.Label(Model.Text);
@Html.CheckBoxFor(m => m.IsSelected);
@Html.HiddenFor(m => m.Id);
@Html.HiddenFor(m => m.Text);
Run Code Online (Sandbox Code Playgroud)