【问题标题】:ASP.NET MVC 5 Edit Option for Complex List Child复杂列表子项的 ASP.NET MVC 5 编辑选项
【发布时间】:2016-12-07 07:18:02
【问题描述】:

我有一个名为 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
   }

根据question 的答案,我将我的 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,那么有没有比手动创建输入标签更好的方法?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 asp.net-mvc-5


    【解决方案1】:

    选项 1:将 foreach 循环替换为 for

    @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

    Step.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。

    【讨论】:

      【解决方案2】:

      看起来很复杂,试试下面的。
      1. 在EditorTemplates文件夹下用模型Step创建一个名为“Step.cshtml”的新编辑器模板(即视图)。
      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)
      

      【讨论】:

      • 不错的答案,但 Zabavsky 快了一分钟,答案几乎相同。
      • @Josh 感谢您的赞赏,我正试图发布您修改后的视图的完整源代码,我在以代码格式呈现时表现不佳,这让我回避了回答。无论人如何,任何方式的答案都有帮助。快乐。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      相关资源
      最近更新 更多