如何使用选择框扩展标识用户属性

时间:2015-02-10 00:47:02

标签: c# asp.net-mvc entity-framework razor asp.net-identity-2

我对剃须刀和mvc控制器的经验很少。我想在注册视图中添加一个下拉框。我在网上的一些例子中尝试了一些不同的东西,但我不知道如何通过应用程序用户访问我需要的类。我想添加公司列表。通过帐户视图模型我真的迷路了。我从公司课上删除了这个关系,因为我不得不把它清理干净。不知道这需要什么。用户只能拥有一家公司。

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> 
        GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager
            .CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }

    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }

公司类

 public class Company
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }

    public List<Document> Documents { get; set; }
}

帐户视图模型

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    [Required]
    [Display(Name = "UserName")]
    public string UserName { get; set; }
    [Required]
    [Display(Name = "CompanyName")]
    public int CompanyId { get; set; }
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

    //Property for the options
    public IEnumerable<SelectListItem> CompanyOptions(string selected)
    {
        //This is just static - get it from somewhere else (database?)
        return new List<SelectListItem>{ 
            new SelectListItem{ Text = "Company 1", Value = "1", Selected = selected.Equals("1") },
            new SelectListItem{ Text = "Company 2", Value = "2", Selected = selected.Equals("2") }
         };
    }
}

查看

<div class="form-group">
  @Html.LabelFor(model => model.CompanyId, new { @class = "control-label col-md-2" })
 <div class="col-md-10">
   @Html.DropDownFor(m => m.CompanyId, Model.CompanyOptions(Model.CompanyId), null)
  </div>

错误消息

  

描述:编译服务此请求所需的资源时发生错误。请查看以下特定错误详细信息并相应地修改源代码。   编译器错误消息:CS1061:&#39; System.Web.Mvc.HtmlHelper&#39;不包含&#39; DropDownFor&#39;的定义没有扩展方法&#39; DropDownFor&#39;接受类型为#System; Web.Mvc.HtmlHelper&#39;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)   来源错误:   第41行:@ Html.LabelFor(model =&gt; model.CompanyId,new {@class =&#34; control-label col-md-2&#34;})   第42行:   第43行:@ Html.DropDownFor(m =&gt; m.CompanyId,Model.CompanyOptions(Model.CompanyId),null)   第44行:   第45行:   块引用

新错误

  

编译器错误消息:CS0121:以下方法或属性之间的调用不明确:&#39; System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper,System.Linq.Expressions。表达式&gt;,System.Collections.Generic.IEnumerable,System.Collections.Generic.IDictionary)&#39;和&#39; System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper,System.Linq.Expressions.Expression&gt;,System.Collections.Generic.IEnumerable,string)&#39;

UserAdmin控制器

// GET: /Users/Create
    public async Task<ActionResult> Create()
    {
        //Get the list of Roles
        ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
        return View();
    }
 // POST: /Users/Create
    [HttpPost]
    public async Task<ActionResult> Create(RegisterViewModel userViewModel, params string[] selectedRoles)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser 
            {
                UserName = userViewModel.UserName,
                Email = userViewModel.Email,
                CompanyId = userViewModel.CompanyId,
                Name = userViewModel.Name
            };


                user.UserName = userViewModel.UserName;
                user.Email = userViewModel.Email;
                user.CompanyId = userViewModel.CompanyId;
                user.Name = userViewModel.Name;

            // Then create:
            var adminresult = await UserManager.CreateAsync(user, userViewModel.Password);

            //Add User to the selected Roles 
            if (adminresult.Succeeded)
            {
                if (selectedRoles != null)
                {
                    var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
                    if (!result.Succeeded)
                    {
                        ModelState.AddModelError("", result.Errors.First());
                        ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Name");
                        return View();
                    }
                }
            }
            else
            {
                ModelState.AddModelError("", adminresult.Errors.First());
                ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
                return View();

            }
            return RedirectToAction("Index");
        }
        ViewBag.RoleId = new SelectList(RoleManager.Roles, "Name", "Name");
        return View();
    }

帐户控制器

// GET: /Account/Register
    [AllowAnonymous]
    public ActionResult Register()
    {
        return View();
    }
// POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, CompanyId = model.CompanyId, Name = model.Name };


            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                var callbackUrl = Url.Action("ConfirmEmail", "Account", 
                    new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                await UserManager.SendEmailAsync(user.Id, 
                    "Confirm your account", 
                    "Please confirm your account by clicking this link: <a href=\"" 
                    + callbackUrl + "\">link</a>");
                ViewBag.Link = callbackUrl;
                return View("DisplayEmail");
            }
            AddErrors(result);
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

注册视图模型

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    [Required]
    [Display(Name = "UserName")]
    public string UserName { get; set; }
    [Required]
    [Display(Name = "CompanyName")]
    public int CompanyId { get; set; }
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

    //Property for the options
    public IEnumerable<SelectListItem> CompanyOptions(int selected)
    {
        //This is just static - get it from somewhere else (database?)
        return new List<SelectListItem>{ 
            new SelectListItem{ Text = "Company 1", Value = "1", Selected = selected.Equals("1") },
            new SelectListItem{ Text = "Company 2", Value = "2", Selected = selected.Equals("2") }
         };
    }
}

2 个答案:

答案 0 :(得分:2)

第二条错误消息是使用null作为DropDownListFor()的第3个参数的结果。该调用不明确,因为它是一个接受string labelOption的重载和一个接受object htmlAttributes的重载

删除第3个参数(或者,如果您需要选项标签,请将其设为string,例如string.Empty"-Please select-"

您也不应该设置Selected的{​​{1}}属性。 SelectListItem绑定到属性@Html.DropDownListFor(m => m.CompanyId, ...,因此如果CompanyId的值与其中一个选项的值匹配,则会选择该选项(如果{{1},请在上面的代码中选择},然后将选择第二个选项)。 CompanyId属性的值将被忽略。而是将CompanyId=2更改为属性

Selected

并在控制器中

CompanyOptions

如果您从数据库访问公司,则更有可能

public IEnumerable<SelectListItem> CompanyOptions { get; set; }

答案 1 :(得分:0)

您需要在注册模型中添加公司列表,在视图中将其显示给用户,然后获取所选值并将其应用到您的后期操作中。

模特:

//Property for the options
public IEnumerable<SelectListItem> CompanyOptions(string selected)
{
    //This is just static - get it from somewhere else (database?)
    return new List<SelectListItem>{ 
        new SelectListItem{ Text = "Company 1", Value = "1", Selected = selected.Equals("1") },
        new SelectListItem{ Text = "Company 2", Value = "2", Selected = selected.Equals("2") }
    };
}

现在我们可以将其呈现给视图:

<div class="form-group">
    @Html.LabelFor(model => model.CompanyId, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(m => m.CompanyId, Model.CompanyOptions(Model.CompanyId), null)
    </div>
</div>

现在,您可以在CompanyId操作中使用模型上的Register属性。