傳入字典的模型項目類型爲'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")
}
您的看法是基於'RegisterViewModelForm',但您將其發回到具有參數'RegisterViewModel'的方法。但'ModelState'是無效的,你返回的視圖,但現在通過它'RegisterViewModel',因此錯誤。你的POST方法必須是'RegisterViewModelForm',如果它是有效的,初始化一個'RegisterViewModel'的新實例將映射其模型的屬性並保存。 –
而'ModelState'將始終無效,因爲'RegisterViewModel'包含一個必需的屬性'UserName',它不在視圖中,所以它始終是'null'。這裏使用2個模型有什麼意義(它們都是視圖模型)。另外'MultiSelectList RolesList'沒有任何意義('MultiSelectList'用於'DropdownListFor()'),你目前的使用意味着你只能選擇一個角色,所以POST方法中的foreach'循環沒有任何意義。 –
視圖確實有一個字段UserName。 –