【问题标题】:Collection property is posted with all null values for properties集合属性与属性的所有空值一起发布
【发布时间】:2018-08-15 03:57:18
【问题描述】:

使用下面指定的视图,我可以很好地获取我的所有属性,并且Team 属性包含正确数量的项目,但所有这些项目的属性都只是null强>...

查看

@using (Html.BeginForm("BuildTeam", "Team", FormMethod.Post, new { crmtItem = Model, team = Model.Team }))
{
    @Html.HiddenFor(m => m.Id);
    @Html.HiddenFor(m => m.ProjectTitle);
    @Html.HiddenFor(m => m.OpportunityStatus);
    @Html.HiddenFor(m => m.ProjectManager);
    @Html.HiddenFor(m => m.ProjectNumber);
    @Html.HiddenFor(m => m.Sector);
    @Html.HiddenFor(m => m.Service);
    @Html.HiddenFor(m => m.Stage);
    for (int i = 0; i < Model.Team.Count(); i++)
    {
        @Html.HiddenFor(m => m.Team[i].DisplayName)
        @Html.HiddenFor(m => m.Team[i].UserName)
    }
    <a class="btn btn-default btn-sm" onclick="location.href='@Url.Action("Index", new { filter= Model.Stage })'"><span class="glyphicon glyphicon-circle-arrow-left"></span></a>
    <a class="btn btn-default btn-sm" href="@Model.WorkspaceUrl"><span class="glyphicon glyphicon-globe"> Workspace</span></a>

    <button type="submit" class="btn btn-default btn-sm pull-right">
        <span class="glyphicon glyphicon-user" /> Team
    </button>
}

视图模型

public class CRMTItemViewModel
{
    public int Id { get; set; }
    public string ProjectTitle { get; set; }
    public string ProjectManager { get; set; }
    public string BidNoBid { get; set; }
    public string OpportunityStatus { get; set; }
    public string Stage { get; set; }
    public string Sector { get; set; }
    public string Service { get; set; }
    public int? CRMTNumber { get; set; }
    public int? ProjectNumber { get; set; }
    public string WorkspaceUrl { get; set; }
    public List<SharePointUser> Team { get; set; }
}

SharePointUser

public class SharePointUser
{
    public string FirstName { get; internal set; }
    public string LastName { get; internal set; }
    public string UserName { get; internal set; }
    public string DisplayName { get; internal set; }
    public string ImagePath { get; internal set; }
    public byte[] ImageBytes { get; internal set; }
    public Guid GUID { get; internal set; }
}

控制器

[HttpPost]
public ActionResult BuildTeam(CRMTItemViewModel crmtItem, List<SharePointUser> team)
{

    return View(crmtItem);
}

我最初在 Controller 中只有 crmtItem 参数,但它仍然失败,所以我尝试将其拆分但没有任何成功。

真的很感谢这方面的任何指导。

【问题讨论】:

  • 首先删除 List&lt;SharePointUser&gt; team 参数 - 您的值将绑定到 TeamCRMTItemViewModel。这个观点有什么意义——它所包含的只是隐藏的输入?
  • 您必须从您的BeginForm() 中删除new { crmtItem = Model, team = Model.Team } - 查看您生成的&lt;form&gt; 元素的action 属性,以了解为什么它永远无法工作
  • @StephenMuecke 该视图显示项目(为简单起见不包括在内),但我有一个按钮,我想调用一个控制器操作,我将项目传递给该按钮
  • 不管你怎么想——你实际上降低了性能——你执行了所有代码来生成所有额外的 html,然后通过网络发送所有额外的 html,然后再次将其全部发送回来而不改变跨度>
  • 正确的性能是钥匙扣。所以你应该只关心隐藏字段中的 id。这就是我的建议

标签: c# asp.net-mvc


【解决方案1】:

总结了cmets和性能方面。对于您的隐藏字段。尝试改用@Html.HiddenFor(Model.Id);

当您需要在最后将结果存储到数据库中时,您也只需要使用对象的 id 进行 db 查询。

(提示:http://www.stackoverflow.com/questions/3866716/what-does-html-hiddenfor-do

【讨论】:

  • 这不是问题的答案(这就是属性未绑定的原因) - 它只是对您已经在 cmets 中做出的更好实践的评论!
  • @Bassie:您已经在文件开头正确定义了视图模型? @Model CRMTItemViewModel
  • @DTeuchert 感谢您的 cmets。是的,视图引用CRMTItemViewModel
【解决方案2】:

DefaultModelBinder 无法设置 SharePointUser 属性的值,因为它们具有 internal 设置器。你需要然后public

public class SharePointUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    ....

此外,您应该删除BeginForm() 方法中的new { crmtItem = Model, team = Model.Team } 路由值。如果您检查 &lt;form&gt; 元素的 action 属性,您会看到它的生成

../Team/BuildTeam?crmtItem=yourAssembly.CRMTItemViewModel&amp;team=System.Collections....

无论如何,它永远无法绑定到您的模型。此外,您不需要在 POST 方法中使用第二个 List&lt;SharePointUser&gt; team 参数,因为(在删除 internal 关键字之后),这些值将绑定到 crmtItemTeam 属性。

话虽如此,您通过生成所有这些隐藏输入所做的只是降低性能。生成所有额外的 html,将其全部发送到客户端,然后将其全部发送回几乎肯定会比再次从数据库中获取模型要慢,并且您现在允许恶意用户更改表单中的值可能会导致其他问题。如果您担心进行另一个数据库调用(应该小于 2 毫秒),您可以随时将其缓存在服务器上(例如在 Session 中)。

只需发回模型的 Id 值,您可以将其作为路由值包含在内(不需要隐藏输入)

@using (Html.BeginForm("BuildTeam", "Team", FormMethod.Post, new { id Model.Id}))

并将 POST 方法更改为

[HttpPost]
public ActionResult BuildTeam(int id)

尽管如果您也有具有相同签名的 [HttpGet] 方法,则可能需要更改该签名

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多