简体   繁体   English

MVC BeginCollectionItem

[英]MVC BeginCollectionItem

I'm having some issue getting my partial view BeginCollectionItem to save to the database. 我在获取部分视图BeginCollectionItem保存到数据库时遇到问题。 I have a form which has a dynamic number of "sections" that can be added to the page, and within each of these fields there is a text box where the user can enter the section name. 我有一个表单,该表单具有可以添加到页面的动态数量的“部分”,并且在每个这些字段中都有一个文本框,用户可以在其中输入部分名称。

As far as I can tell the BeginCollectionItem within the partial view is working properly, however I cannot post the info to the database. 据我所知,部分视图中的BeginCollectionItem正常工作,但是我无法将信息发布到数据库中。 In my other forms I have used a [bind()] to send the data to the database, is it possible to get this into a list and then post that via a bind? 在其他形式中,我使用[bind()]将数据发送到数据库,是否可以将其放入列表,然后通过绑定将其发布?

I've included my code below: The Model: 我在下面包含了我的代码: 模型:

namespace project.Models.SetupViewModels
{
    public class SOPTopTemplateBuilderViewModel
    {
        public List<Section> Section { get; set; }
    }

    public class Section {
        public int SectionId { get; set; }
        public string SectionText { get; set; }
        public string TopTempId { get; set; }
    }
}

cshtml: cshtml:

    @model IEnumerable<project.Models.SetupViewModels.Section>
    @using (Html.BeginForm("SOPTopTemplateBuilder", "Setup", FormMethod.Post))
    {
     <div class="main-holder" id="theform">
     @foreach(var item in Model)
     {
         @Html.Partial("_SectionCreator", item)
     }
     </div>
     <button id="add" type="button">Add</button>
         <div class="form-group submit-row">
              <div class="col-12 float-to-right">
                   <input type="submit" class="btn btn-default" value="continue" />
              </div>
         </div>
    }
@section Scripts {
    <script>
$(document).ready(function () {
        var url = '@Url.Action("AddSection")';
        var form = $('form');
        var recipients = $('#theform');
        $('#add').click(function() {
            $.post(url, function(response) {
                recipients.append(response);
                // Reparse the validator for client side validation
                form.data('validator', null);
                $.validator.unobtrusive.parse(form);
                });
            });
        });
    </script>
}

Partial View: 部分视图:

@model project.Models.SetupViewModels.Section
@using HtmlHelpers.BeginCollectionItemCore

@using (Html.BeginCollectionItem("Section"))
{
    <div class="new-section">
        <div>
            <p>New Section</p>
             @Html.HiddenFor(m => m.SectionId, new { @class="id" })
            @Html.EditorFor(m => m.SectionText, new { @class = "form-control limit-form"})
         </div>
    </div>
}

Controller: 控制器:

[HttpPost]
public PartialViewResult AddSection()
{      
      return PartialView("_SectionCreator", new Section());
}

[HttpGet]
public ActionResult SOPTopTemplateBuilder(){

      List<Section> model = new List<Section>();

      return View(model);
}

[HttpPost]
public ActionResult SOPTopTemplateBuilder(IEnumerable<Section> soptop)
{
      if (ModelState.IsValid)
      {}
      return View(soptop);
}

Your use of Html.BeginCollectionItem("Section") perpends Section[xxxx] to the name attribute (where xxxx is a Guid ) so that you generating inputs with 您对Html.BeginCollectionItem("Section")Section[xxxx]附加到name属性(其中xxxxGuid ),以便使用

<input name="Section[xxxx].SectionId" .... />

which posts back to a model containing a collection property named Sections . 它回发到包含名为Sections的集合属性的模型。

Since you already have a model with that property, you can change the POST method to 由于您已经拥有具有该属性的模型,因此可以将POST方法更改为

[HttpPost]
public ActionResult SOPTopTemplateBuilder(SOPTopTemplateBuilderViewModel soptop)

other options include 其他选项包括

  1. Using your existing POST method and omitting the "Section" prefix using Html.BeginCollectionItem("") which will generate name="[xxxx].SectionId" 使用您现有的POST方法,并使用Html.BeginCollectionItem("")省略“ Section”前缀,这将生成name="[xxxx].SectionId"
  2. Changing the POST method signature to public ActionResult SOPTopTemplateBuilder(IEnumerable<Section> section) (where the name of the parameter matches the name of the prefix) 将POST方法签名更改为public ActionResult SOPTopTemplateBuilder(IEnumerable<Section> section) (其中参数名称与前缀名称匹配)
  3. Using a BindAttribute to 'strip' the prefix from the form values public ActionResult SOPTopTemplateBuilder([Bind(Prefix = "Section")]IEnumerable<Section> soptop) 使用BindAttribute从表单值中“剥离”前缀public ActionResult SOPTopTemplateBuilder([Bind(Prefix = "Section")]IEnumerable<Section> soptop)

As a side note, your editing data, so you should always use a view model (say public class SectionViewModel ) rather than using data models in your view. 附带说明一下,您在编辑数据,因此您应该始终使用视图模型(例如, public class SectionViewModel ),而不是在视图中使用数据模型。 - What is ViewModel in MVC? -MVC中的ViewModel是什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM