2015-09-26 51 views
0

传入字典的模型项目类型为'Posts.Models.RegisterViewModel',但此字典需要类型为'Posts.Models.RegisterViewModelForm'的模型项目传入字典的模型属于A类型,但需要B类

好吧,这是我每次尝试注册一个使用我在C#上使用ASP.NET开发的博客网站的用户时发生的错误。

最令人困惑的部分是它几个月前工作得很好。我的教授甚至在我面前对这部分进行了测试,并且通过了大胆的色彩。我在我的旧笔记本电脑上开发了这个项目,它没有Windows 8.1,我现在正在使用Microsoft Visual Studio 2015。

我试着将post方法的参数注册到RegisterViewModelForm,但它没有奏效,我也尝试调试它。它执行得很好,直到它到达提交按钮,之后发生这个错误。

任何帮助将不胜感激。

我的模型

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

    [Required] 
    [Display(Name = "User Name")] 
    public string UserName { 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] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)] 
    [Display(Name = "First name(s)")] 
    public string FirstName { get; set; } 

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

    public System.Web.Mvc.MultiSelectList RolesList { get; set; } 
} 

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

    [Required] 
    [Display(Name = "First Name")] 
    public string FirstName { get; set; } 

    [Required] 
    [Display(Name = "Last Name")] 
    public string LastName { get; set; } 

    [Required] 
    [Display(Name = "User Name")] 
    public string UserName { 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; } 

    public List<string> Roles { get; set; } 
} 

我控制器

// 
    // GET: /Account/Register 
    [AllowAnonymous] 
    public ActionResult Register() 
    { 
     //return View(); 

     var registerForm = new RegisterViewModelForm(); 

     registerForm.RolesList = new MultiSelectList(new List<string> { "Administrator", "Blogger", "Commenter" }); 
     //registerForm.RolesList = new MultiSelectList(new List<string> {"Blogger", "Commenter" }); 



     return View(registerForm); 
    } 

    // 
    // POST: /Account/Register 
    [HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { Email = model.Email,UserName = model.UserName, FirstName = model.FirstName, LastName = model.LastName }; 
      var result = await UserManager.CreateAsync(user, model.Password); 
      if (result.Succeeded) 
      { 
       //await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 

       //await UserManager.AddClaimAsync(user.Id, new Claim("http://http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "administrator")); 

       //await UserManager.AddClaimAsync(user.Id, new Claim("http://http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "blogger")); 

       //await UserManager.AddClaimAsync(user.Id, new Claim("http://http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "commenter")); 

       await UserManager.AddClaimAsync(user.Id, new Claim(ClaimTypes.Email, model.Email)); 
       await UserManager.AddClaimAsync(user.Id, new Claim(ClaimTypes.GivenName, model.FirstName)); 
       await UserManager.AddClaimAsync(user.Id, new Claim(ClaimTypes.Surname, model.LastName)); 
       await UserManager.AddClaimAsync(user.Id, new Claim(ClaimTypes.Role, "User")); 

       // Add 'role' claims 

       foreach (var role in model.Roles) 
       { 
        await UserManager.AddClaimAsync(user.Id, new Claim(ClaimTypes.Role, role)); 
       } 

       await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 


       // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 
       // Send an email with this link 
       // string 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 <a href=\"" + callbackUrl + "\">here</a>"); 

       return RedirectToAction("Create", "Pictures"); 
      } 
      AddErrors(result); 
     } 

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

我的观点

@model Posts.Models.RegisterViewModelForm 
 
@{ 
 
    ViewBag.Title = "Register"; 
 
} 
 

 
<h2>@ViewBag.Title.</h2> 
 

 
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 
 
{ 
 
    @Html.AntiForgeryToken() 
 
    <h4>Create a new account.</h4> 
 
    <hr /> 
 
    @Html.ValidationSummary("", new { @class = "text-danger" }) 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.TextBoxFor(m => m.LastName, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 
    <div class="form-group"> 
 
     @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 
 
     <div class="col-md-10"> 
 
      @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 
 
     </div> 
 
    </div> 
 

 
    <div class="form-group"> 
 
     <label class="control-label col-md-2" for="Roles">Roles</label> 
 
     <div class="col-md-10"> 
 
      @{ 
 
    foreach (var item in Model.RolesList) 
 
    { 
 
     <div class="checkbox"> 
 
      <label> 
 
       <input type="radio" name="Roles" value="@item.Text" />@item.Text 
 
      </label> 
 
     </div> 
 
    } 
 
      } 
 
     </div> 
 
    </div> 
 

 
    <div class="form-group"> 
 
     <div class="col-md-offset-2 col-md-10"> 
 
      <input type="submit" class="btn btn-default" value="Register" /> 
 
     </div> 
 
    </div> 
 
} 
 

 

 
@section Scripts { 
 
    @Scripts.Render("~/bundles/jqueryval") 
 
}

+0

您的看法是基于'RegisterViewModelForm',但您将其发回到具有参数'RegisterViewModel'的方法。但'ModelState'是无效的,你返回的视图,但现在通过它'RegisterViewModel',因此错误。你的POST方法必须是'RegisterViewModelForm',如果它是有效的,初始化一个'RegisterViewModel'的新实例将映射其模型的属性并保存。 –

+0

而'ModelState'将始终无效,因为'RegisterViewModel'包含一个必需的属性'UserName',它不在视图中,所以它始终是'null'。这里使用2个模型有什么意义(它们都是视图模型)。另外'MultiSelectList RolesList'没有任何意义('MultiSelectList'用于'DropdownListFor()'),你目前的使用意味着你只能选择一个角色,所以POST方法中的foreach'循环没有任何意义。 –

+0

视图确实有一个字段UserName。 –

回答

0

检查出你的POST方法:它应该是一个RegisterViewModelForm。如果它不起作用,请清理并重建所有内容。

public async Task<ActionResult> Register(RegisterViewModelForm model) 
+0

我尝试了这两种方法。没有工作 –

+0

我想我明白了:你打控制器后的方法?如果ModelState无效,则返回View(RegisterViewModel),但该视图需要Posts.Models.RegisterViewModelForm。 –

+0

我认为这也是问题,但我不知道为什么会发生。我不明白为什么和我的模型状态无效。 –