【问题标题】:ASP MVC3 - BeginCollectionItem returning nullsASP MVC3 - BeginCollectionItem 返回空值
【发布时间】:2013-04-01 07:44:16
【问题描述】:

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

在我的模型BankListMaster 中,我有一个单独的模型BankAgentIdICollection 对象。 BankListMasterBankListAgentId 在我们的 SQL 数据库中具有一对多的关系。

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

如果我选择Add another,那么,按照blog post 上的说明,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 从 post 上的表单发送回控制器的内容。索引为123 的项目是最初从数据库中提取的项目。最后一项是通过对局部视图的 jQuery/Ajax 调用添加的。

【问题讨论】:

  • 这越来越复杂 Neal :) 首先,您需要分享控制器的后期动作,所以我们知道您在动作中“捕捉”了什么。二、你用fiddler吗?查看发布到控制器的内容对您非常有用。
  • @Mariusz.W:告诉我这件事.... Fiddler pic 根据请求添加。
  • Fiddler 列表中的最后一项包含 2 次具有相同键的 FixedOrVariable 字段条目。但是没有 TableId 字段。不知道为什么会这样,因为您在上面发布的部分观点看起来不错,但只是认为值得指出......
  • 我也有同样的问题,有人解决了吗?
  • @DylanSlabbinck - 我已经坚持了几个月,最后不得不继续前进。如果您找到解决方案,请发布。将非常感激。

标签: jquery asp.net-mvc-3 asp.net-mvc-2 icollection


【解决方案1】:

我的解决方案是: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>  

 }

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

【讨论】:

  • 你是如何让计数器进入局部视图的?
【解决方案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
        });
    }
}

似乎对我来说解决这个问题的方法是将数据发送为x-www-form-urlencoded(jQuery 的 AJAX 的默认contentType)而不是json。因此,我将 AJAX 调用更改为以下内容:

$.ajax({
    type: 'POST',
    url: this.action,
    data: $(this).serialize()
});

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 2011-11-27
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多