用于复杂列表子项的ASP.NET MVC 5编辑选项

本文关键字:MVC NET 编辑 选项 ASP 复杂 列表 用于 | 更新日期: 2023-09-27 18:27:07

我有一个名为Job的对象,其中一个属性是步骤列表:

public class Job
{
    [Display(Name = "Id")]
    public int? JobId { get; set; }
    [Required]
    public string Name { get; set; }
    public List<Step> Steps { get; set; }
    public Job()
    {
        Steps = new List<Step>();
    }
}
public class Step
{
    public int? StepId { get; set; }
    public int JobId { get; set; }
    [Required]
    public string Name { get; set; }
}

我有一个JobController,它具有以下操作来执行更新:

   // PUT: /Job/Edit/5
   [HttpPut]
   public ActionResult Edit(Job model)
   {
     // Logic to update model here
   }

根据这个问题的答案,我更新了我的UI(使用MVC5附带的Bootstrap模板)为:

@using (Html.BeginForm())
{
    @Html.HttpMethodOverride(HttpVerbs.Put)
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.JobId)
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
        <h3>Steps</h3>
        <div>
            @foreach (var item in Model.Steps)
            {
                <div class="form-group">
                    @Html.Hidden("Steps[" + stepIndex + "].StepId", item.StepId)
                    @Html.LabelFor(modelItem => item.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        <input class="form-control text-box single-line" data-val="true" data-val-required="The Name field is required."
                               id="@String.Format("Steps_{0}__Name", stepIndex)" name="@String.Format("Steps[{0}].Name", stepIndex)" type="text" value="@item.Name" />
                     @Html.ValidationMessageFor(modelItem => item.Name, "", new { @class = "text-danger" })
                    </div>
                </div>
                stepIndex += 1;
                <hr />
            }
        </div>
        <div class="form-group">
             <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Save" class="btn btn-default" />
                </div>
            </div>
        </div>
}

正如你所看到的,我必须手动构建输入标记,而不是使用Html.EditorFor。原因是我需要控制id的名称,以便它将索引传递到id和名称中。我认为有一种更好的方法可以让MVC使用labelFor、EditorFor和ValidationMessageFor来呈现正确的值。

我的问题是:

  1. 是否有一组控件可以用于MVC5,使我能够在不经过这些额外步骤的情况下渲染复杂的子对象
  2. 如果1上没有,那么有比手动创建输入标签更好的方法吗

用于复杂列表子项的ASP.NET MVC 5编辑选项

选项1:用for:替换foreach循环

@for (int i = 0; i < Model.Steps.Count; i++)
{
    <div class="form-group">
        @Html.HiddenFor(m => m.Steps[i].StepId)
        @Html.TextBoxFor(m => m.Steps[i].Name, new { @class = "form-control text-box single-line" })
        ...
    </div>
}

选项2:为Step类创建一个名为Step.chtml的编辑器模板,并使用EditorFor:

步骤.chtml

@model Step
<div class="form-group">
    @Html.HiddenFor(m => m.StepId)
    @Html.TextBoxFor(m => m.Name, new { @class = "form-control text-box single-line" })
    ...
</div>

主视图

<h3>Steps</h3>
<div>
    @Html.EditorFor(m => m.Steps)
<div>

通过这两种方式,框架将为输入提供正确的名称和id。

如果事情看起来很复杂,请尝试以下操作
1.使用模型Step在EditorTemplates文件夹下创建一个名为"Step.cs.html"的新编辑器模板(这是一个视图)
2.在执行以下代码时,
Step.cshtml

@model Step
<div class="form-group">
@Html.HiddenFor(model => model.StepId)
@Html.LabelFor(modelItem => modelItem.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
    @Html.TextBoxFor(model => model.Name, htmlAttributes: new { @class = "form-control text-box single-line" })
    @Html.ValidationMessageFor(modelItem => modelItem.Name, "", new { @class = "text-danger" })
</div>

3.从视图中删除foreach语句,并将编辑器模板调用为

@Html.EditorFor(model => model.Steps)