6

我正在尝试使用Steve Sanderson 的关于将集合项绑定到模型的博客文章。但是,我看到一些奇怪的行为,我在帖子或其他讨论中找不到答案。

在我的模型BankListMaster中,我有ICollection一个单独的模型对象BankAgentIdBankListMaster并且BankListAgentId在我们的 SQL 数据库中有一对多的关系。

我在Edit页面上遇到了问题。当页面加载时,我们当前与BankListMaster我正在使用的项目关联的三个代理 ID 会正确加载。但是,如果我点击“保存”,我会看到ICollection对象 ( bankListAgentId) 包含三个项目,但每个字段都包含一个null值。

如果我选择Add another,则按照博客文章中的说明,Ajax 会调用部分视图,该视图会正确附加到表中。

现在,如果我点击“保存”,我会看到ICollection对象计数增加了一个项目,计数为 4。最初加载的所有项目都GET包含null字段值,但新附加项目的AgentIdStateCode字段包含正确的信息(但是,新项目的所有其他字段都是null)。

对 ASP MVC 来说还是比较新的,所以我不确定发生了什么或看什么方向。

这是主视图中的表格。我已经在有和没有这些@Html.Hidden物品的情况下尝试过这个,并收到了相同的结果。

@model Monet.Models.BankListMaster

@{
    ViewBag.Title = "Edit";
}
    <fieldset>
        <legend>Stat(s) Fixed</legend>
        <table id="fixedRows">
            <thead>
                <tr>
                    <th>State Code</th>
                    <th>Agent ID</th>
                    <th></th>
                    <th></th>
                </tr>
           </thead>
           <tbody>

                @for (int i = 0; i < Model.Fixed.Count; i++)
                {
                     using (Html.BeginCollectionItem("BankListAgentId"))
                    {                        
                             @Html.HiddenFor(m => Model.Fixed[i].BankID)
                             @Html.HiddenFor(m => Model.Fixed[i].TableId)
                             @Html.HiddenFor(m => Model.Fixed[i].FixedOrVariable)   
                            <tr>
                                <td>
                                    @Html.DropDownListFor(m => Model.Fixed[i].StateCode,
                                        (SelectList)ViewBag.StateCodeList, Model.Fixed[i].StateCode)
                                </td>
                                <td>
                                    @Html.TextBoxFor(m => Model.Fixed[i].AgentId)
                                    @Html.ValidationMessageFor(m => Model.Fixed[i].AgentId)
                                </td>
                                <td>
                                    <a href="javascript:void(0)" class="deleteRow">delete</a>
                                </td>
                                @*<td><a href="#" onclick="$('#item-@Model.AgentId').parent().remove();" style="float:right;">Delete</a></td>*@
                            </tr>  

                    }
                }

           </tbody>

        </table>
        <br />
        <a href="javascript:void(0)" class="addFixed">Add Another</a>
    </fieldset>

这是部分视图。同样,我尝试了使用和不使用这些@Html.Hidden项目并收到相同的结果。

@model Monet.Models.BankListAgentId

@{
    Layout = null;
}
@using (Html.BeginCollectionItem("BankListAgentId"))
{ 
    @Html.HiddenFor(model => model.TableId)        
    @Html.HiddenFor(model => model.BankID)
    @Html.HiddenFor(model => model.FixedOrVariable)

    <tr>
        <td>
            @Html.DropDownListFor(model => model.StateCode,
                (SelectList)ViewBag.StateCodeList, Model.StateCode)
        </td>
        <td>
            @Html.EditorFor(model => model.AgentId)
            @Html.ValidationMessageFor(model => model.AgentId)
        </td>
        <td>
            <a href="javascript:void(0)" class="deleteRow">delete</a>

        </td>
        @*<td><a href="#" onclick="$('#item-@Model.AgentId').parent().remove();" style="float:right;">Delete</a></td>*@
    </tr>
}

这是 Ajax 调用

$(document).ready(function () {

    $(".addFixed").click(function () {
        $.ajax({
            url: '@Url.Action("BlankFixedRow", "BankListMaster")',
            dataType: 'html',
            cache: false,
            success: function (html) {
                $("#fixedRows > tbody").append('<tr>' + html + '</tr>');
            }
        });
    });
});

这是调用局部视图的控制器方法

    public ViewResult BlankFixedRow()
    {
        SelectList tmpList = new SelectList(new[] { "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NA", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "US", "VT", "VI", "VA", "WA", "WV", "WI", "WY" });
        ViewBag.StateCodeList = tmpList;

        return View("FixedPartialView", new BankListAgentId());
    }

这是BankListMaster模型

public partial class BankListMaster
{
    public BankListMaster()
    {
        this.BankListAttachments = new HashSet<BankListAttachments>();
        this.BankListAgentId = new HashSet<BankListAgentId>();
    }

    public int ID { get; set; }
    public string BankName { get; set; }
    public string LastChangeOperator { get; set; }
    public Nullable<System.DateTime> LastChangeDate { get; set; }

    public virtual ICollection<BankListAttachments> BankListAttachments { get; set; }
    public virtual ICollection<BankListAgentId> BankListAgentId { get; set; }
}

这就是BankListAgentId模型

public partial class BankListAgentId
{
    public string AgentId { get; set; }
    public int BankID { get; set; }
    public string FixedOrVariable { get; set; }
    public string StateCode { get; set; }
    public int TableId { get; set; }

    public virtual BankListMaster BankListMaster { get; set; }
}

这是通过 fiddler 从帖子上的表单发送回控制器的内容。索引为123的项目是最初从数据库中提取的项目。最后一项是通过对局部视图的 jQuery/Ajax 调用添加的。

在此处输入图像描述

4

2 回答 2

2

我的解决方案是: html.beginCollectionItem 中使用的所有内容都必须在部分视图中。所以你的解决方案可能是这样的:

主视图

 @model Monet.Models.BankListMaster

 @{
     ViewBag.Title = "Edit";
 }
     <fieldset>
         <legend>Stat(s) Fixed</legend>
         <table id="fixedRows">
         <thead>
              <tr>
                   <th>State Code</th>
                   <th>Agent ID</th>
                   <th></th>
                   <th></th>
             </tr>
        </thead>
        <tbody>

            @for (int i = 0; i < Model.Fixed.Count; i++)
            {
                 @Html.Partial("name", item)     
            }

       </tbody>

    </table>
    <br />
    <a href="javascript:void(0)" class="addFixed">Add Another</a>
</fieldset>

局部视图“名称”

 @model Monet.Models.BankListMaster

 using (Html.BeginCollectionItem("BankListAgentId"))
 {                        
      @Html.HiddenFor(m => Model.Fixed[i].BankID)
      @Html.HiddenFor(m => Model.Fixed[i].TableId)
      @Html.HiddenFor(m => Model.Fixed[i].FixedOrVariable)   
      <tr>
           <td>
                @Html.DropDownListFor(m => Model.Fixed[i].StateCode,
                  (SelectList)ViewBag.StateCodeList, Model.Fixed[i].StateCode)
           </td>
           <td>
                @Html.TextBoxFor(m => Model.Fixed[i].AgentId)
                @Html.ValidationMessageFor(m => Model.Fixed[i].AgentId)
           </td>
           <td>
                <a href="javascript:void(0)" class="deleteRow">delete</a>
           </td>
           @*<td><a href="#" onclick="$('#item-@Model.AgentId').parent().remove();" style="float:right;">Delete</a></td>*@
           </tr>  

 }

这不是完整的解决方案,但你必须这样做,它对我有用。希望这会有所帮助!

于 2013-07-10T07:21:04.277 回答
2

我被困在一个类似的问题上几个小时。我的项目集合 (Choices) 在包含多个项目时将返回 null。但是,就像您一样,我的数据似乎渲染得很好:

{
    "QuestionTemplateId":"1",
    "Position":"0",
    "CardId":"1",
    "Label":"Question#1",
    "AdminComments":"",
    "Type":"ComboBox",
    "ModelType":"MyProject.Areas.DGM.Models.ViewModels.Controls.ComboBoxViewModel",
    "ComboQuestionId":"1",
    "Choices.Index": ["dc0e6eea-5a8e-4971-8f9f-4d6e1c290300","52f2b780-c21e-4633-b880-bdff5d815eaf"],
    "Choices[dc0e6eea-5a8e-4971-8f9f-4d6e1c290300].Label":"Choice #1",
    "Choices[dc0e6eea-5a8e-4971-8f9f-4d6e1c290300].Score":"4",
    "Choices[52f2b780-c21e-4633-b880-bdff5d815eaf].Label":"Choice #2",
    "Choices[52f2b780-c21e-4633-b880-bdff5d815eaf].Score":"7"
}

然后我意识到我的问题可能与数据 POST 有关。当用户提交表单时,我会进行以下AJAX调用:

$("#questionForm").on('submit', function () {
    if ($(this).valid()) {
        var data = $(this).serializeObject(); // from here: http://stackoverflow.com/a/1186309/2835243
        $.ajax({
            type: 'POST',
            url: this.action,
            contentType: 'application/json',
            data: JSON.stringify(data) // this is what generated the above JSON
        });
    }
}

对我来说似乎解决它的方法是将数据发送为( jQuery 的 AJAXx-www-form-urlencoded的默认值)而不是. 因此,我将 AJAX 调用更改为以下内容:contentTypejson

$.ajax({
    type: 'POST',
    url: this.action,
    data: $(this).serialize()
});
于 2016-07-19T13:38:57.883 回答