嵌套的BeginCollectionItem

noo*_*obi 11 nested partial dynamically-generated asp.net-mvc-3

我正在使用Steve Sanderson的BeginCollectionItem方法来添加动态内容.当我在第一级做它时,一切正常.但是,当尝试实现嵌套集合意味着另一个BeginCollectionItem中的BeginCollectionItem时,它似乎不起作用.

我的模型如下:

public class Order
{

        [Key]
        [HiddenInput]
        public int id { get; set; }

        [Display(Name = "Order number")]
        public string number { get; set; }

        ...

        [Display(Name = "Payment method")]
        public List<PaymentMethod> payment_methods { get; set; }

        ...
}

public class PaymentMethod
{
        public MethodOfPayment method { get; set; }
        public CC cc { get; set; }
        public CASH cash { get; set; }
        public TT tt { get; set; }
}

public class TT
{
        [Key]
        public int id { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Total amount")]
        public double? total_value { get; set; }

        ...

        [Display(Name = "Transfers")]
        public List<Transfer> transfers { get; set; }
}

public class Transfer
{
        [Key]
        public int id { get; set; }

        [Display(Name = "Payment")]
        public int payment_id { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "SWIFT")]
        public string swift { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Amount transferred")]
        public double? transfer_amount { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Date transferred")]
        public DateTime transfer_date { get; set; }

        ...
}
Run Code Online (Sandbox Code Playgroud)

现在我所拥有的订单可能有多种付款方式,如果其中一种付款方式是TT(电传转账),则可能涉及多次转账.在一个订单中实现多个支付方法作为集合可以工作,但是当我尝试在TT中实现多个传输时,这些传输中的任何一个都不会传递给控制器​​.

这是我的观点:

@model prj.Models.Model.Order

@using (Html.BeginForm("Create")){
@Html.ValidationSummary(true, "Creation was unsuccessful. Please correct the errors and try again.")

...

@Html.TextBoxFor(m => m.number, new { id = "txtnumber" })

...


<div id="editorPaymentRows">
    @foreach (var payment in Model.payment_methods)
    {
        @Html.Partial("_NewPayment", payment)
    }
</div>

}
Run Code Online (Sandbox Code Playgroud)

在_NewPayment部分:

@using prj.Helpers 
@model prj.Models.Model.PaymentMethod

<div class="editPaymentRow">

@using (Html.BeginCollectionItem("payment_methods"))
{
...

<div class="editor-label">
    @Html.LabelFor(m => m.tt.total_value)<req>*</req>      
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.tt.total_value)
</div>

...


<div id="editorTransferRows">
   @if (Model.tt != null)
{
    foreach (var transfer in Model.tt.transfers)
    {
         @Html.Partial("_NewTransfer", transfer)
    }
}
...
</div>



}

</div>
Run Code Online (Sandbox Code Playgroud)

最后在_NewTransfer部分:

@using prj.Helpers 
@model prj.Models.Model.Transfer
...

<div class="editTransferRow">
//using (Html.BeginCollectionItem("transfers"))
@using (Html.BeginCollectionItem("tt.transfers"))
{
...

<div class="editor-label">
    @Html.LabelFor(m => m.swift)<req>*</req>      
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.swift, new { @class = "t_swift" })
</div>

...

<div class="editor-label">
    @Html.LabelFor(m => m.transfer_amount)<req>*</req>      
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.transfer_amount, new { @class = "t_transfer_amount" })
</div>

...
}

</div>
Run Code Online (Sandbox Code Playgroud)

所以一切正常,除了在控制器中,List传输在PaymentMethods的TT属性中始终为null.它没有正确传递给控制器​​.有什么我想念的吗?

嵌套的BeginCollectionItem不起作用吗?我必须做一个额外的步骤吗?请说清楚.谢谢


我用以下链接中显示的Joe Stevens的方法想出来了:

http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/

干杯

Jon*_*onK 16

要获取前缀Html.BeginCollectionItem,您可以访问ViewData.TemplateInfo.HtmlFieldPrefix(我正在使用nuget包).你在正确的轨道上tt.transfers,但你需要特定的前缀.

而不仅仅是

Html.BeginCollectionItem("tt.transfers")
Run Code Online (Sandbox Code Playgroud)

你还需要当前payment_method的前缀.

@{
    var paymentMethodPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
}
@using (Html.BeginCollectionItem(paymentMethodPrefix + ".tt.transfers"))
Run Code Online (Sandbox Code Playgroud)

快速测试看起来你也可以:

@using (Html.BeginCollectionItem(ViewData.TemplateInfo.HtmlFieldPrefix + ".tt.transfers"))
Run Code Online (Sandbox Code Playgroud)