【问题标题】:ASP NET MVC 4 collection is null on postASP NET MVC 4 集合在发布时为空
【发布时间】:2014-10-12 17:48:24
【问题描述】:

我阅读了大部分 Google 内容 :-),但无法继续。无论我做什么,我的对象上的集合都是并且在发布时保持为空。

我的模特:

public class ArticleViewModel
{
    public Guid EventId { get; set; }
    public IList<ArticleItemViewModel> ArtikelListe { get; set; }

    public decimal GesamtpreisNetto { get; set; }
    public decimal MwSt { get; set; }
}

和

public class ArticleItemViewModel
{
    public Guid EventId { get; set; }
    public Guid Id { get; set; }

    public string Artikelname { get; set; }
    public string Artikelname_EN { get; set; }

    public string Information { get; set; }
    public string Information_EN { get; set; }

    public decimal Preis { get; set; }

    public bool MitAnzahl { get; set; }
    public bool IstKategorie { get; set; }

    public int Anzahl { get; set; }
    public bool Checkbox { get; set; }

    public int Reihenfolge { get; set; }
}

我的看法:

@using (Html.BeginForm("Next", "Article", FormMethod.Post))
{
@Html.HiddenFor(x => x.EventId)

<input type="hidden" name="ArtikelListe" />

for (var i = 0; i < Model.ArtikelListe.Count; i++)
//  foreach (EventManager.ViewModels.ArticleItemViewModel artikelItem in Model.ArtikelListe)
{               
    <div>
        <div>
            @if (Model.ArtikelListe[i].IstKategorie)
            {
                @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
                @Html.LabelFor(x => x.ArtikelListe[i].Information)
            }
            else
            {
                if (Model.ArtikelListe[i].MitAnzahl)
                {
                    @Html.TextBoxFor(x => x.ArtikelListe[i].Anzahl, new { @class = "field text fn" })
                }
                else
                {
                    @Html.LabelFor(x => x.ArtikelListe[i].Anzahl)                     
                }

                @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
                @Html.LabelFor(x => x.ArtikelListe[i].Information)
            }        
        </div>
    </div>
}

在帖子中,我取回了我的 Viewmodel,它有一个包含 15 个项目的 ArtikelListe 集合(这是正确的),但这些都是空的!

在我的 HTTP 标头中,我得到以下帖子数据:

EventId:824e7f3c-7190-4ebb-aa60-51b57c977b1e
ArtikelListe:
ArtikelListe[1].Anzahl:0
ArtikelListe[2].Anzahl:1
ArtikelListe[3].Anzahl:0
submitButton:Nächste

我想知道为什么在 http 帖子中只发送部分数据以及为什么我的所有列表项都是空的。我试图通过 for 和 foreach 进行渲染。同样的结果。

有什么想法吗?我很无奈。

【问题讨论】:

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


    【解决方案1】:

    集合索引器必须从零开始并且是连续的(除非您包含Index 属性)。由于您的if 语句,您不必为属性Anzahl 生成控件。查看您的标题信息,您没有ArtikelListe[0].Anzahl 的值,这意味着第一项必须具有IstKategorie=true 或MitAnzahl=false。您可以通过添加隐藏输入来更正此问题,以便返回值

    @if (Model.ArtikelListe[i].IstKategorie)
    {
      @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
      @Html.LabelFor(x => x.ArtikelListe[i].Information)
      @Html.HiddenFor(x => x.ArtikelListe[i].Anzahl) // add this
    }
    else
    {
      if (Model.ArtikelListe[i].MitAnzahl)
      {
        @Html.TextBoxFor(x => x.ArtikelListe[i].Anzahl, new { @class = "field text fn" })
      }
      else
      {
        @Html.LabelFor(x => x.ArtikelListe[i].Anzahl)
        @Html.HiddenFor(x => x.ArtikelListe[i].Anzahl) // add this         
      }
      @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
      @Html.LabelFor(x => x.ArtikelListe[i].Information)
    }
    

    或者,您可以添加一个Index 属性,DefaultModelBinder 使用该属性来匹配不连续的集合项

    @if (Model.ArtikelListe[i].IstKategorie)
    {
      @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
      @Html.LabelFor(x => x.ArtikelListe[i].Information)
    }
    else
    {
      if (Model.ArtikelListe[i].MitAnzahl)
      {
        @Html.TextBoxFor(x => x.ArtikelListe[i].Anzahl, new { @class = "field text fn" })
        <input type="hidden" name="x.ArtikelListe.Index" value="@i" /> // add this manually
      }
      else
      {
        @Html.LabelFor(x => x.ArtikelListe[i].Anzahl)     
      }
      @Html.LabelFor(x => x.ArtikelListe[i].Artikelname)<br />  
      @Html.LabelFor(x => x.ArtikelListe[i].Information)
    }
    

    使用第一个选项,它将回发所有项目。在第二种情况下,它将仅回发满足if 条件的项目。

    请注意,正如 Sergey 所说,您还需要删除 &lt;input type="hidden" name="ArtikelListe" /&gt;

    【讨论】:

      【解决方案2】:

      这一行的问题:

      <input type="hidden" name="ArtikelListe" />
      

      当 POST 请求返回时:

      ArtikelListe:
      ArtikelListe[1].Anzahl:0
      ArtikelListe[2].Anzahl:1
      ArtikelListe[3].Anzahl:0
      

      然后ArtikelListe 覆盖列表的值,这就是它始终为空的原因。 因此,您只需要将隐藏字段重命名为其他名称,以免与现有名称冲突。

      这是基于您在 DotNetFiddle 中的 MVC 代码的工作示例 - https://dotnetfiddle.net/BCXduq

      您可以点击运行,然后在右下角的两个输入字段中输入一些值,然后点击保存按钮。然后它将服务器在 POST 中收到的模型显示为 JSON 文本。

      【讨论】:

      • 谢谢你!如果我删除,整个集合在发布时为空。我现在会检查你的代码。
      • 如果我删除或重命名隐藏字段名称。这就是我想说的:-)
      • 您的代码运行良好。但是我的代码中仍然有一个空集合。你还有什么改变吗?我就是不明白……
      • 检查我指定的 DotNetFiddle 链接。它在那里工作,Anzahl 参数适用于服务器端,并且集合有 2 个与 UI 上相同的项目。也许你有不同的代码影响它?
      【解决方案3】:

      谢谢你们。

      问题是,我使用 Fiddle 的脚本进行了测试。在这段代码中

      Model.ArtikelListe[i].MitAnzahl
      

      总是如此。

      如果不正确,则值“Anzahl”未绑定到包含值(而只是标签)的控件。

      @Html.LabelFor(x => x.ArtikelListe[i].Anzahl)
      

      只要我在该范围内插入一个隐藏字段并将“Anzahl”值绑定到它,帖子就会返回我期望的所有数据。

      还是谢谢。我学到了很多!

      【讨论】:

      • 哇。我给你详细而正确的答案,而不是接受它,你发布这个。连赞成票都没有。祝您在未来获得任何帮助时好运。
      • 斯蒂芬,对不起我的错。从那以后已经很久了,所以我不知道我是错过了你的答案还是只是不知道更好。下次拍前请先问清楚。谢谢。
      猜你喜欢
      • 2014-08-17
      • 1970-01-01
      • 2016-02-13
      • 2018-12-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 2011-11-20
      • 1970-01-01
      相关资源
      最近更新 更多