【问题标题】:Showing Type instead of data in DropDownListFor()在 DropDownListFor() 中显示类型而不是数据
【发布时间】:2017-09-05 15:38:27
【问题描述】:

尝试使用 ViewModel 填充用户和角色,但它显示类型而不是 System.Data.Entity.DynamicProxies.AppUser.xxx(对于用户)和 System.Data.Entity.DynamicProxies.IdentityRole.xxx(对于角色)。

代码如下。

public class AppUser : IdentityUser
    {
        //add custom properties which have not included in IdentityUser before
        public string Designation { get; set; }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<AppUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here 
            return userIdentity;
        }

        public static ERPContext Create()
        {
            return new ERPContext();
        }
    } 



public class AppRole : IdentityRole
    {
        public AppRole() : base() { }
        public AppRole(string name) : base(name) { }
        // extra properties here 
        public string Description { get; set; }
    }

视图模型

public class UserAssignRoleViewModel
    {

        public string Username { get; set; }

        public string Role { get; set; }
        [Required]
        public List<AppUser> Users { get; set; }
        [Required]
        public List<IdentityRole> Roles { get; set; }

        public int SelectedId { set; get; }

        public int SelectedRoleId { set; get; }
    }

角色控制器

  public ActionResult ManageUserRoles()
        {
            //this code is also an alternate way to fetch the roles from Owin // Startup config
            // var roles = HttpContext.GetOwinContext().GetUserManager<RoleManager<IdentityRole>>().Roles;
            //var rolelist = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            var model = new UserAssignRoleViewModel();
            var users = context.Users.ToList();
            users.Select(s => new SelectListItem
            {
                Value = s.Id.ToString(),
                Text = s.UserName.ToString()
            });
            var roles = context.Roles.ToList();
            roles.Select(s => new SelectListItem
            {
                Value = s.Id.ToString(),
                Text = s.Name.ToString()
            });
            ViewBag.Users = users;
            //var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            //ViewBag.Roles = list;
            model.Users = users;
            model.Roles = roles;
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult RoleAddToUser(string UserName, string RoleName)
        {
            AppUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
            var userManager = new UserManager<AppUser>(new UserStore<AppUser>(context));

            userManager.AddToRole(user.Id, RoleName);

            ViewBag.ResultMessage = "Role Assigned successfully !";

            // prepopulat users for the view dropdown
            var _users = context.Users.OrderBy(r => r.UserName).ToList().Select(rr => new SelectListItem { Value = rr.UserName.ToString(), Text = rr.UserName }).ToList();
            ViewBag.Users = _users;
            // prepopulat roles for the view dropdown
            var _roles = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = _roles;

            return View("ManageUserRoles");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult GetRoles(string UserName)
        {
            if (!string.IsNullOrWhiteSpace(UserName))
            {
                AppUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
                var userManager = new UserManager<AppUser>(new UserStore<AppUser>(context));

                ViewBag.RolesForThisUser = userManager.GetRoles(user.Id);


                // prepopulat roles for the view dropdown
                var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
                ViewBag.Roles = list;
                // prepopulat roles for the view dropdown
                var users = context.Users.OrderBy(r => r.UserName).ToList().Select(rr => new SelectListItem { Value = rr.UserName.ToString(), Text = rr.UserName }).ToList();
                ViewBag.Users = users;
            }

            return View("ManageUserRoles");
        }

上面的代码几乎没有我之前尝试过的注释代码。

最后,视图如下

@model ERPLite.Models.UserAssignRoleViewModel
@{
    ViewBag.Title = "ManageUserRoles";

}

@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />


@using (Html.BeginForm("RoleAddToUser", "Role"))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)


    <p>

        User Name: @Html.DropDownListFor(x => x.SelectedId, new SelectList(Model.Users), "Select")
        @*Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")*@
        Role Name: @Html.DropDownListFor(u => u.SelectedRoleId, new SelectList(Model.Roles), "Select ...")
    </p>

    <input type="submit" value="Save" />
}
<hr />
<h3>Get Roles for a User</h3>
@using (Html.BeginForm("GetRoles", "Role"))
{
    @Html.AntiForgeryToken()
    <p>
        Username : @Html.TextBox("UserName")
        <input type="submit" value="Get Roles for this User" />
    </p>
}

@if (ViewBag.RolesForThisUser != null)
{
    <div style="background-color:yellow;">
        <h3>Roles for this user </h3>
        <ol>
            @foreach (string s in ViewBag.RolesForThisUser)
            {
                <li>@s</li>
            }
        </ol>
    </div>
}

当我使用 ViewBag 时,它工作得很好,除了 Validation for theDropdowns (Required Validation) 无法实现,因此在这种情况下采用带有必需注释的 ViewModel 和 ViewModel 是推荐的方式。 感谢任何帮助。提前致谢 。 使用 MVC 5、CodeFirst EF 和 Identity。

【问题讨论】:

  • 使用带有测试值字段名称参数的SelectList 构造函数重载。例如new SelectList(Model.Users, "id", "Username")
  • [Required] 添加到List&lt;IdentityRole&gt; Roles 是没有意义的。您将所选选项绑定到int SelectedRoleId,因此它的属性需要[Required] 属性(它也应该是int?
  • @StephenMuecke 谢谢。还有一个疑问,如果我使用 SelectedId 那么在下拉绑定中我也必须使用相同的权利吗?
  • 如果你想让用户为第一个下拉列表选择一个值,那么你的属性应该是[Required (ErrorMessage = "Please select a user")]public int? SelectedId { get; set; }。另请参阅What does it mean for a property to be Required and nullable?

标签: asp.net-mvc entity-framework asp.net-identity viewmodel


【解决方案1】:

您在视图模型中使用身份模型而不是 SelectListItem

在你的视图模型改变

    [Required]
    public List<AppUser> Users { get; set; }
    [Required]
    public List<IdentityRole> Roles { get; set; }

    public List<SelectListItem> Users { get; set; }
    public List<SelectListItem> Roles { get; set; }

并将Required 属性添加到SelectedIdSelectedRoleId

在您的 ManageUserRoles 操作中,将您的视图模型的人口更改为

        model.Users = users.Select(s => new SelectListItem
        {
            Value = s.Id.ToString(),
            Text = s.UserName.ToString()
        });
        var roles = context.Roles.ToList();
        model.Roles = roles.Select(s => new SelectListItem
        {
            Value = s.Id.ToString(),
            Text = s.Name.ToString()
        });

顺便说一句,像这样使用Select()

var roles = context.Roles.ToList();
        roles.Select(s => new SelectListItem
        {
            Value = s.Id.ToString(),
            Text = s.Name.ToString()
        });

什么都不做。您必须将Select 的结果分配给一个变量。

【讨论】:

  • 感谢您的回答。有什么方法可以使用 List Users 而不是 SelectedListItem?
  • @user2695433,你到底为什么要这样做。它是一个视图模型,视图模型的全部目的是将正确的数据传递给视图,并且您的视图需要IEnumerable&lt;SelectListItem&gt; 作为下拉菜单,而不是List&lt;AppUser&gt;
  • 您需要从UsersRoles 属性中删除[Required] 属性(否则ModelState 将在POST 方法中无效)
  • @StephenMuecke 我在复制和粘贴代码时忽略了这一点。现在已经修好了。
猜你喜欢
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多