简体   繁体   English

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

[英]Binding issue in a list at a complex model to an mvc application

I'm new using .NET MVC Web Application. 我是使用.NET MVC Web应用程序的新手。 I'm using the version 4 of Web Application. 我正在使用Web应用程序的第4版。 I'm developing a page to manage the roles of the simple membership provider, and I want to it be dynamically. 我正在开发一个页面来管理简单成员资格提供者的角色,我希望它是动态的。 To clear what I mean, it would be something like this: 为了清楚我的意思,它将是这样的:

UsersInRoles

Something really simple as that. 这样的事情非常简单。 To do so, I have a complex ViewModel such as this: 为此,我有一个复杂的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());
    }
}

In my View, I have something like this to display the role names: 在我的视图中,我有类似的东西来显示角色名称:

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

And, I have a DisplayTemplates Folder, with the AllRoleNames.cshtml file in it, and here is what's inside (I'm not worried about the layout of the page yet): 而且,我有一个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])
    } 
}

So far, so good. 到现在为止还挺好。 It displays the name correctly. 它正确显示名称。 But, when I try to press the Save button, the MVC should get the proper names from the html to bind to object Model in my HTTP Post Controller Action: 但是,当我尝试按下Save按钮时,MVC应该从html中获取正确的名称以绑定到HTTP Post Controller Action中的对象Model:

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

But I get an empty model. 但我得到一个空模型。 (I'm just worried to the list of roles name for now, because once I figure out what's happening with it, I can also figure out what's happening with my list of UserInRoles object). (我只是担心现在的角色名称列表,因为一旦我弄清楚它发生了什么,我也可以弄清楚我的UserInRoles对象列表发生了什么)。

I could find out why the MVC is not binding correctly. 我可以找出为什么MVC没有正确绑定。 It's because the html generated is something like this: 这是因为生成的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

The name attribute is being generated as "AllRoleNames.[0]" when it should be "AllRoleNames[0]". name属性生成为“AllRoleNames。[0]”时应为“AllRoleNames [0]”。 There is an extra dot there. 那里有一个额外的点。 So, I found this question with a hack proposed by the answer. 所以,我发现这个问题的答案提出了一个黑客。 It could work, but when I tested, I saw that my HtmlFieldPrefix already was without the dot, so of course it didn't work. 它可以工作,但是当我测试时,我看到我的HtmlFieldPrefix已经没有点,所以当然它不起作用。

My question is, why is MVC generating these names with the dots, and is there a way to tell it to generate it correctly? 我的问题是,为什么MVC用点生成这些名称,有没有办法告诉它正确生成它? I hope my question is clear, but if not, I can provide more details. 我希望我的问题很清楚,但如果没有,我可以提供更多细节。 Thanks in advance! 提前致谢!

I have found that passing a List as the model is nothing but pain. 我发现传递List作为模型只不过是痛苦。 If you pass a class that contains the List life becomes much easier. 如果传递包含List生命的类变得更容易。 You can then use a for loop and things will start behaving the way you expect them to. 然后,您可以使用for循环,事情将按照您期望的方式开始。 ie

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

should yield your property names correctly. 应该正确地产生你的属性名称。

Thats occur because you are using a for cycle instead of a foreach , try with this in the AllRoleNames template: 这是因为你使用for循环而不是foreach ,在AllRoleNames模板中尝试使用它:

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

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM