将复杂模型的列表中的问题绑定到mvc应用程序

时间:2014-02-18 13:37:02

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

我是使用.NET MVC Web应用程序的新手。我正在使用Web应用程序的第4版。 我正在开发一个页面来管理简单成员资格提供者的角色,我希望它是动态的。为了清楚我的意思,它会是这样的:

UsersInRoles

真的很简单。为此,我有一个复杂的ViewModel,例如:

public class UserInRolesModel
{
    public List<string> AllRoleNames { get; set; }
    public List<UserInRoles> UsersInRoles { get; set; }

    public UserInRolesModel()
    {
        AllRoleNames = new List<string>();
        UsersInRoles = new List<UserInRoles>();
    }

    public UserInRolesModel(List<string> allRoleNames, List<UserInRoles> usersInRoles)
    {
        AllRoleNames = allRoleNames;
        UsersInRoles = usersInRoles;
    }
}

public class UserInRoles
{
    public UserInRoles(string user, List<string> userRoles, IEnumerable<string> allRoleNames)
    {
        User = user;
        Roles = SetRoles(userRoles, allRoleNames);
    }

    private List<bool> SetRoles(List<string> userRoles, IEnumerable<string> allRoleNames)
    {
        return allRoleNames.Select(userRoles.Contains).ToList();
    }

    public string User { get; set; }
    public List<bool> Roles { get; set; }

    public void UpdateRoles(List<string> allRoleNames)
    {
        var roleProvider = (SimpleRoleProvider)System.Web.Security.Roles.Provider;

        var rolesAdded = new List<string>();
        for (int i = 0; i < Roles.Count; i++)
        {
            if (Roles[i])
            {
                rolesAdded.Add(allRoleNames[i]);
            }
        }
        roleProvider.AddUsersToRoles(new[] { User }, rolesAdded.ToArray());
    }
}

在我的视图中,我有类似的内容来显示角色名称:

<th><strong>@Html.DisplayFor(m => m.AllRoleNames, "AllRoleNames")</strong></th>

而且,我有一个DisplayTemplates文件夹,其中包含AllRoleNames.cshtml文件,这里面是什么(我不担心页面的布局):

@model List<string>

@if (Model != null)
{ 
    for (int i = 0; i < Model.Count; i++)
    {
        @Html.HiddenFor(m => m[i])
        @Html.DisplayFor(m => m[i])
    } 
}

到目前为止,这么好。它正确显示名称。 但是,当我尝试按下Save按钮时,MVC应该从html中获取正确的名称以绑定到HTTP Post Controller Action中的对象模型:

[HttpPost]
public ActionResult AdminUsers(UserInRolesModel model)
{
    //code to save roles goes here
    return View(model);
}

但我得到一个空模型。 (我只是担心现在的角色名称列表,因为一旦我弄清楚它发生了什么,我也可以弄清楚我的UserInRoles对象列表发生了什么。)

我可以找出为什么MVC没有正确绑定。这是因为生成的html是这样的:

<input id="AllRoleNames__0_" name="AllRoleNames.[0]" type="hidden" value="Admin">
Admin
<input id="AllRoleNames__1_" name="AllRoleNames.[1]" type="hidden" value="Extrator">
Extrator

当name属性应为“AllRoleNames [0]”时,将生成名称属性为“AllRoleNames。[0]”。那里有一个额外的点。所以,我发现this question有一个答案提出的黑客。它可以工作,但是当我测试时,我看到我的HtmlFieldPrefix已经没有了点,所以当然它没有用。

我的问题是,为什么MVC用点生成这些名称,有没有办法告诉它正确生成它?我希望我的问题很清楚,但如果没有,我可以提供更多细节。 提前谢谢!

2 个答案:

答案 0 :(得分:3)

我发现传递List作为模型只不过是痛苦。如果传递包含List生命的类变得更容易。然后,您可以使用for循环,事情将按照您期望的方式开始。即。

for(int i = 0; i < model.MyList.Count; i++)
{
    @Html.HiddenFor(model => model.MyList[i])
    @Html.DisplayFor(model  => model.MyList[i])
} 

应正确生成您的属性名称。

答案 1 :(得分:0)

这是因为您使用的是for周期而不是foreach,请在AllRoleNames模板中尝试使用此功能:

foreach (var role in Model)
{
    @Html.HiddenFor(m => role)
    @Html.DisplayFor(m => role)
} 

希望它有所帮助。