使用编辑器在一个表单中提供多个模型

本文关键字:表单 模型 一个 编辑器 | 更新日期: 2023-09-27 18:34:14

我正在尝试使用 .net 4.5、实体 5、MVC 4 创建一个简单的多模型表单

根据我看到的示例,我希望 EditorTemplates''Tasks.cshtml 呈现两次,一次用于项目中的每个任务,但它似乎只被调用一次并传递了我似乎无法使用的任务集合。

有什么想法吗? 下面列出了我的类/视图。

任务:

public partial class Task
{
    public Task()
    {
        this.TaskPeople = new HashSet<TaskPerson>();
    }
    public int Id { get; set; }
    public string Title { get; set; }
    public int ProjectId { get; set; }
    public virtual Project Project { get; set; }
    public virtual ICollection<TaskPerson> TaskPeople { get; set; }
}    

项目:

public partial class Project
{
    public Project()
    {
        this.Tasks = new HashSet<Task>();
    }
    public int Id { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Task> Tasks { get; set; }
}

HomeController.New():

public ActionResult New()
{
    Project project = new Project();
    project.Tasks.Add(new Task() { });
    project.Tasks.Add(new Task() { });
    return View(project);
}

Home/New.cshtml:

@using (Html.BeginForm("Create", "Home", FormMethod.Post))
{    
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()    
    @Html.LabelFor(m => m.Title)    
    @Html.EditorFor(m => m.Tasks, "Tasks")
    <input type="submit" value="Save" />
}

Home/EditorTemplates/Tasks.cshtml

@model IEnumerable<MvcApplication5.Models.Task>
@Html.TextBoxFor(m => m.Title) // Error Here

编辑:

如果我从 Tasks.cshtml 中取出 IEnumerable 并将其替换为

@model MvcApplication5.Models.Task

我得到以下异常:

The model item passed into the dictionary is of type 'System.Collections.Generic.HashSet`1[MvcApplication5.Models.Task]', but this dictionary requires a model item of type 'MvcApplication5.Models.Task'.

使用编辑器在一个表单中提供多个模型

Home/EditorTemplates/Tasks.cshtml中,模型IEnumerable但是,要呈现文本框,您不会循环浏览列表。

不确定当您尝试访问 Title 属性时如何不收到运行时错误,因为该属性在IEnumerable<MvcApplication5.Models.Task>中不存在

您对模板的理解有点偏差,所以让我看看是否可以提供帮助。

Html.Display*Html.Editor*帮助程序都能够识别您何时向他们传递集合。 这些方法不必循环遍历该集合,而是会针对该集合的每个元素重复调用集合的基础类型的模板。

简单来说,如果将List<Car>传递给这些方法之一,如果Car.cshtml模板存在,它将为该列表中的每个Car重复调用该模板。 在您的情况下,这意味着将代码更改为如下所示的内容:

@using (Html.BeginForm("Create", "Home", FormMethod.Post))
{    
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()    
    @Html.LabelFor(m => m.Title)    
    @Html.EditorFor(m => m.Tasks)
    <input type="submit" value="Save" />
}

然后模板Task.cshtml

@model MvcApplication5.Models.Task
@Html.TextBoxFor(m => m.Title)

这是模型

public class TSubject
{
    public string Title { get; set; }
    public bool IsSelected { get; set; }
}
public class TMonth
{
    public string Title { get; set; }
    public bool IsSelected { get; set; }
}

public class TModel
{
    public List<TSubject> Subjects { get; set; }
    public List<TMonth> Months { get; set; }
}

控制器

[HttpGet]
    public ActionResult Test1()
    {
        TModel model = new TModel
        {
            Months = new List<TMonth>
            {
                new TMonth
                {
                    IsSelected = false, Title = "January"
                },
                new TMonth
                {
                    IsSelected = true, Title = "Feburary"
                },
                new TMonth
                {
                    IsSelected = false, Title = "March"
                },
                new TMonth
                {
                    IsSelected = true, Title = "April"
                },
                new TMonth
                {
                    IsSelected = true, Title = "May"
                },
                new TMonth
                {
                    IsSelected = false, Title = "June"
                },
                new TMonth
                {
                    IsSelected = false, Title = "July"
                },
                new TMonth
                {
                    IsSelected = true, Title = "August"
                },
            },
            Subjects = new List<TSubject>
            {
                new TSubject
                {
                    Title = "Biology", IsSelected = false, 
                },
                new TSubject
                {
                    Title = "Chemistry", IsSelected = false,
                },
                new TSubject
                {
                    Title = "Physics", IsSelected = true,
                },
                new TSubject
                {
                    Title = "English", IsSelected = false,
                },
                new TSubject
                {
                    Title = "Urdu", IsSelected = false,
                },
                new TSubject
                {
                    Title = "Islamic Studies", IsSelected = true,
                },
            }
        };
        return View(model);
    }
    [HttpPost]
    public ActionResult Test1(TModel mod)
    {
        if(ModelState.IsValid)
        {
            ViewBag.Title = "All OK";
        }
        return View(mod);
    }

网页视图

@model ZiaratToursMVC.ZiaratModels.TModel
<h1>Subject list</h1>
<table class="table table-bordered">
    <tr>
        <th>Subject</th>
        <th>Is selected</th>
    </tr>
    <tbody>
        @Html.EditorFor(a => a.Subjects)
    </tbody>
</table>
<p></p>
<h1>Month list</h1>
<table class="table table-bordered">
    <tr>
        <th>Month</th>
        <th>Is selected</th>
    </tr>
    <tbody>
        @Html.EditorFor(a => a.Months)
    </tbody>
</table>

编辑器模板.cs

@model ZiaratToursMVC.ZiaratModels.TMonth
<tr>
<td>
    @Html.HiddenFor(a => a.Title)
    @Model.Title
</td>
<td>
    @Html.CheckBoxFor(a => a.IsSelected)
</td>

编辑器.cs

模板
@model ZiaratToursMVC.ZiaratModels.TSubject
<tr>
<td>
    @Html.HiddenFor(a => a.Title)
    @Model.Title
</td>
<td>
    @Html.CheckBoxFor(a => a.IsSelected)
</td>