使用MVC中的自定义方法填充@ Html.DropDownListFor()

Pha*_*m98 1 selectlist roleprovider html.dropdownlistfor asp.net-mvc-3

好的,这是我的问题.我试图填充@Html.DropDownListFor()我的角色减去Admin角色.这很好用,但它显示了所有角色:

@Html.DropDownListFor(m => m.RoleName, new SelectList(Roles.GetAllRoles()))
Run Code Online (Sandbox Code Playgroud)

然而,这显示了所有角色,包括Adminroll.

所以我UserHelper.cs用这个方法创建了另一个类,基本上是这样的Roles.GetAllRoles():

public string[] GetUserRoles()
    {
        string[] userroles = null;
        using (MainVeinDataDataContext conn = new MainVeinDataDataContext())
        {
            userroles = (from r in conn.Roles
                         where r.Rolename != "Admin"
                         select r.Rolename).ToArray();
        }
        return userroles;
    }
Run Code Online (Sandbox Code Playgroud)

但是,作为MVC的新手,我不知道如何将此方法公开给视图中的DropDownList.所以无论我尝试什么,这都行不通:

@Html.DropDownListFor(m => m.RoleName, new SelectList(GetUserRoles()))
Run Code Online (Sandbox Code Playgroud)

我不确定我错过了什么,这让我发疯.希望那里有人知道我错过了什么.

Dar*_*rov 6

视图不应该负责从某些数据源中提取数据.它应该只负责操纵控制器以vie模型的形式传递的数据.

你要做的是反MVC模式.您在此GetUserRoles方法中放置的代码是控制器(或数据访问层)的责任,其结果应该是您的视图模型的一部分.例如,您将拥有以下视图模型:

public class MyViewModel
{
    public string RoleName { get; set; }
    public IEnumerable<SelectListItem> UserRoles { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后你将有一个控制器动作来填充这个视图模型:

public ActionResult Foo()
{
    // The GetUserRoles could also be part of a repository
    // that you would invoke here
    var userRoles = GetUserRoles();

    // Now construct the view model that you will pass to the view
    var model = new MyViewModel
    {
        UserRoles = userRoles.Select(x => new SelectListItem
        {
            Value = x,
            Text = x
        })
    };
    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

现在在你看来:

@model MyViewModel

@Html.DropDownListFor(
    m => m.RoleName, 
    new SelectList(Model.UserRoles, "Value", "Text")
)
Run Code Online (Sandbox Code Playgroud)