Collection属性与属性

时间:2018-03-07 06:13:35

标签: c# asp.net-mvc

使用下面指定的视图,我可以很好地获取所有属性,并且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);
}

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

真的对此提出任何指导。

2 个答案:

答案 0 :(得分:1)

DefaultModelBinder无法设置SharePointUser属性的值,因为他们拥有internal个设置者。您需要制作public

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

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

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

无论如何都永远无法绑定到你的模型。此外,您不需要POST方法中的第二个List<SharePointUser> team参数,因为(afetr删除了internal个关键字),这些值将绑定到Team crmtItem属性}。

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

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

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

并将POST方法更改为

[HttpPost]
public ActionResult BuildTeam(int id)

如果您还拥有使用相同签名的[HttpGet]方法,则可能需要更改该签名

答案 1 :(得分:0)

总结评论和绩效方面。对于你隐藏的领域。请尝试使用@Html.HiddenFor(Model.Id);

当您需要在结束时将结果存储在数据库中时,您还只需要使用对象的id作为db查询。

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