2015-02-10 182 views
3

我对剃须刀和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> 

错误消息

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. Compiler Error Message: CS1061: 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'DropDownFor' and no extension method 'DropDownFor' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?) Source Error: Line 41: @Html.LabelFor(model => model.CompanyId, new { @class = "control-label col-md-2" }) Line 42: Line 43: @Html.DropDownFor(m => m.CompanyId, Model.CompanyOptions(Model.CompanyId), null) Line 44: Line 45: Blockquote

新的错误

Compiler Error Message: CS0121: The call is ambiguous between the following methods or properties: 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable, System.Collections.Generic.IDictionary)' and 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable, string)'

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

第二个错误消息是对DropDownListFor()的第三个参数使用null的结果。电话是模糊的,因为是接受string labelOption接受object htmlAttributes

取出第三个参数(或者,如果你想要一个选项标签,使之成为string,例如string.Empty,或者"-Please select-"

过载和一个您也不应设置SelectListItemSelected财产。 @Html.DropDownListFor(m => m.CompanyId, ...对属性CompanyId有约束力,所以如果CompanyId的值与其中一个选项的值相匹配,那么将选择该选项(在上面的代码中,如果CompanyId=2,则将选择第二个选项)。Selected属性的值将被忽略。相反,改变CompanyOptions一个属性

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

,并在控制器

public ActionResult Create() 
{ 
    RegisterViewModel model = new RegisterViewModel(); 
    model.CompanyId = 2; // set this if you want to display a specific company 
    ConfigureViewModel(model); 
    return View(model); 
} 

public ActionResult Create(RegisterViewModel model) 
{ 
    if(!ModelState.IsValid) 
    { 
    ConfigureViewModel(model); 
    return View(model); 
    } 
    // Save and redirect 
} 

private void ConfigureViewModel(RegisterViewModel model) 
{ 
    model.CompanyOptions = new List<SelectListItem>() 
    { 
    new SelectListItem() { Text = "Company 1", Value = "1" }, 
    new SelectListItem() { Text = "Company 2", Value = "2" } 
    }; 
} 

如果您的访问从一个数据库,它更可能是企业要

model.CompanyOptions = new SelectList(db.Companies, "ID", "Name") 
+0

好看起来不错。我确实需要一些帮助。我正在使用包含用户角色和UserAdmin控件的种子项目。所以还有一些我习惯的控制器。你能帮助放置你的代码吗?我更新了我的帖子 – texas697 2015-02-12 18:35:21

+0

我不明白你的评论。你有什么问题?你的'Create()'方法看起来很奇怪 - 除了设置'user'的值两次,'params string [] selectedRoles'是什么?为什么'selectedRoles'不是视图模型的属性,你如何渲染'selectedRoles'的控件?你编辑只是重复(我认为)原来的'RegisterViewModel',所以我有点困惑。在任何情况下,它似乎并不涉及你原来的问题或你得到的错误,所以它应该是一个新问题 – 2015-02-12 22:17:43

+0

这就是问题,这是一个种子项目,我用它,因为它有userroles和用户管理就绪去。我真的不知道它是如何设置的。我只习惯拥有一个账户控制器,它有一个账户控制器和一个userAdmin控制器。所以当我试图插入你的东西时,我有点迷茫。稍后我会再次处理它。我仍然计划给你信贷给你的帮助。谢谢 – texas697 2015-02-13 00:25:01

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> 

现在你可以在Register行动使用模型上的CompanyId财产。

+0

我更新我的职务。需要一些帮助。谢谢 – texas697 2015-02-10 12:12:35

+0

我的不好 - 见更新。应该是'DropDownListFor'。 – 2015-02-10 12:19:33

+0

不用担心,但现在得到这个'TransparentEnergy.Models.RegisterViewModel.CompanyOptions(string)'的最佳重载方法匹配有一些无效参数 – texas697 2015-02-10 12:26:50