【问题标题】:List<T> submit form binding in MVC5List<T> 在 MVC5 中提交表单绑定
【发布时间】:2016-02-13 16:01:29
【问题描述】:

我对 MVC5 还很陌生。到目前为止,我似乎已经找到了解决问题的方法,但是,我遇到了一个我无法找到解决方案的问题。

我正在创建两个视图,一个用于创建新文章帖子,一个用于编辑当前文章帖子。

我的文章模型如下:

public class Article
{
    private int? _id;

    [BsonRequired]
    [DataType(DataType.Text)]
    [BsonElement("_id")]
    public int? Id
    {
        get { return _id ?? 999999; }
        set { _id = value; }
    }

    ...
    [HiddenInput]
    [BsonElement("related")]
    public List<Related> Related { get; set; }

    [HiddenInput]
    [BsonElement("comments")]
    public List<Comment> Comments { get; set; }

    [HiddenInput]
    [BsonElement("auto_publish")]
    public AutoPublish AutoPublish { get; set; }

}
}

我的问题在于模型项列表(如 List&lt;Comment&gt;List&lt;Related&gt;)和自定义模型属性。

在我的发布和编辑视图中,我为我的所有模型属性设置了 @Html.HiddenFor 属性,但是我很难丢失我的自定义模型属性的值(比如 AutoPublish)和我的模型属性列表。

如果我错了,请纠正我,但对于字符串项目列表,我使用了以下逻辑:

     for (var i = 0; i < Model.Categories.Count; i++)
{
    @Html.HiddenFor(model => Model.Categories[i])
}

对于其他自定义列表,我尝试使用以下代码创建一个 DisplayTemplate:

@model List<CMS.Models.Comment>

@foreach (var item in Model)
{
    @Html.HiddenFor(x => item.Date)
    @Html.HiddenFor(x => item.Email)
    @Html.HiddenFor(x => item.Enabled)
    @Html.HiddenFor(x => item.Ip)
    @Html.HiddenFor(x => item.Username)
    @Html.HiddenFor(x => item.PostId)
    @Html.HiddenFor(x => item.Text)
}

但是,当我尝试在视图中使用 @Html.DisplayForModel("Comments", Model.Comments) 时,模型类型不匹配。

有人可以指出我正确的方向吗? 非常感谢您的宝贵时间。

【问题讨论】:

  • 视图顶部的 using 语句是什么样的?
  • @using (Html.BeginForm("Edit", "Editor", FormMethod.Post, new { id = "form-edit-post" })) 这就是 using 的样子跨度>
  • 这是您认为的第一行吗?
  • 不,这是@model CMS.Models.Article 的第一行

标签: model asp.net-mvc-5 html-helper


【解决方案1】:

DisplayForModel 特定于视图的模型。您不能将任何随机对象传递给它。您可能正在寻找DisplayFor(m =&gt; m.Comments),但请记住,当您将枚举传递给DisplayFor 时,它实际上会为集合中的每个 项呈现显示模板。换句话说,您需要删除部分视图中的foreach,并将模型声明更改为单个Comment,而不是List&lt;Comment&gt;

编辑

实际上,既然您正在渲染HiddenInputs,这应该是一个编辑器 模板,并且您应该使用EditorForDisplayFor 仅用于展示。我所说的所有其他内容仍然适用于EditorFor

【讨论】:

  • 感谢您抽出宝贵时间@Chris Pratt。我已经从(现在)EditorTemplate 中删除了 foreach,删除了 List 并使用了一个 Comment,现在使用 @Html.EditorFor(x => x.Comments, "Comments")。但是,由于在我的文章模型中,评论是评论列表,我仍然得到模型不匹配,说字典需要单个评论而不是列表。我应该为每个评论使用 for 循环吗?就像我在字符串列表中所做的那样?
  • 这可能是因为您传递了一个明确的编辑器模板引用。只需调用@Html.EditorFor(x =&gt; x.Comments) 并确保您有一个名称与单个实例的类名完全匹配的编辑器模板,大概是Comment。 Razor 将负责其余的工作。如果您传递一个明确的模板以供使用,那么 Razor 就会让您对所有事情负责,因此您实际上在模板中需要该 foreach。然而,这样做几乎违背了EditorFor 的全部目的。您不妨将代码直接放在视图中。
  • 再次感谢克里斯。只是为了说清楚:我有一个 html 助手,所以 @Html.EditorFor(x => x.Comments),我在 ~/Views/Shared/EditorTemplates 中有一个 Comment.cshtml。我的 Comment.cshtml 是一堆 HiddenFor,用于我在 Comment 中的 6 个属性并使用 Comment 模型。
  • 通过使用上面的方法,查看页面源代码,我现在可以看到:System.Collections.Generic.List1[CMS.Models.Comment]&lt;input id="Comments" name="Comments" type="hidden" value="System.Collections.Generic.List1[CMS.Models.Comment]" /&gt; 并且我得到一个模型验证错误{"The parameter conversion from type 'System.String' to type 'CMS.Models.Comment' failed because no type converter can convert between these types."}
  • 在大多数情况下,这是人为错误(也就是我的错误)。为了在发布这个问题之前完成这项工作,我为我的List&lt;T&gt; 省略了[HiddenInput],这反过来又呈现了一个隐藏的输入字段,如上所述。删除该属性可以使其正常工作。感谢您为我指明正确的方向,克里斯。似乎我还有很多东西要学习 MVC 才能成为有竞争力的人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 2014-09-27
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
相关资源
最近更新 更多