我有以下3个类(现在包括所有代码)......
using System.ComponentModel.DataAnnotations;
namespace MyWebApp.Models
{
public class ApplicationUser
{
[Display(Prompt = "Your Name", Name = "Contact Name"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Please enter a valid contact")]
public string ContactName { get; set; }
[Display(Name = "Username", Prompt = "Login As"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Your username must be at least 3 characters")]
public string UserName { get; set; }
}
public class Account
{
[Display(Name = "Account Type", Prompt = "Account Type"), Required()]
public int AccountType { get; set; }
[Display(Name = "Organisation Name", Prompt = "Name of Organisation"), StringLength(255)]
public string OrganisationName { get; set; }
}
public class RegisterViewModel
{
public ApplicationUser ApplicationUser { get; set; }
public Account Account { get; set; }
public RegisterViewModel()
{
ApplicationUser = new ApplicationUser();
Account = new Account();
}
[Display(Name = "Password", Prompt = "Password"), Required(), DataType(DataType.Password), StringLength(255, MinimumLength = 5, ErrorMessage = "The password must be at least 7 characters")]
public string Password { get; set; }
[Display(Name = "Confirm Password", Prompt = "Confirm Password"), DataType(DataType.Password), Compare("Password", ErrorMessage = "Your confirmation doesn't match...")]
public string PasswordConfirmation { get; set; }
}
}
我的控制器看起来像这样......
using System.Web.Mvc;
using MyWebApp.Models;
namespace MyWebApp.Controllers
{
[Authorize]
public class AccountController : Controller
{
// GET: /Account/
[AllowAnonymous]
public ActionResult Register()
{
RegisterViewModel mdl = new RegisterViewModel();
return View(mdl);
}
[HttpPost]
[AllowAnonymous]
public ActionResult Register([Bind(Include = "Account.AccountType, ApplicationUser.ContactName, ApplicationUser.UserName, Password, Account.OrganisationName, Account.OrganisationRegistrationNumber, Account.AddressLine1, Account.AddressLine2, Account.AddressLine3, Account.City, Account.County, Account.Postcode, ApplicationUser.Email, ApplicationUser.PhoneNumber, PasswordConfirmation")]RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = model.ApplicationUser;
var associatedAccount = model.Account;
var u1 = Request.Form["ApplicationUser.UserName"];
if (u1 == user.UserName)
{
// we got it
ViewBag.Message = "We got it";
}
else
{
// no we didn't
ViewBag.Message = "We failed!";
}
return View(model);
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
}
我的Register.cshtml视图看起来像这样......
@using MyWebApp.Models
@model MyWebApp.Models.RegisterViewModel
@{
ViewBag.Title = "Register User";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>New Account</h4>
<hr />
<p>@ViewBag.Message</p>
@Html.ValidationSummary(true)
<div class="col-md-6">
<div class="form-group">
@Html.LabelFor(model => model.ApplicationUser.ContactName, new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.EditorFor(model => model.ApplicationUser.ContactName, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ApplicationUser.ContactName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ApplicationUser.UserName, new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.EditorFor(model => model.ApplicationUser.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ApplicationUser.UserName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.EditorFor(model => model.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Password)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PasswordConfirmation, new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.EditorFor(model => model.PasswordConfirmation, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.PasswordConfirmation)
</div>
</div>
</div>
<div class="col-md-6">
<div class="org-info">
<div class="form-group">
@Html.LabelFor(model => model.Account.OrganisationName, new { @class = "control-label col-md-5" })
<div class="col-md-7">
@Html.EditorFor(model => model.Account.OrganisationName, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Account.OrganisationName)
</div>
</div>
</div>
<hr />
<div class="form-group">
<div class="col-md-8"></div>
<div class="col-md-4">
<input type="submit" value="Sign Up" class="btn btn-default form-control" />
</div>
</div>
</div>
</div>
}
我的问题是,当用户点击注册而不在视图中输入任何详细信息时,只有密码和密码确认字段显示有问题,没有任何帐户或ApplicationUser属性显示问题。
如果我输入密码和确认字段的详细信息并在Register方法中放置一个断点,即使我没有添加任何帐户或用户详细信息,ModelState.IsValid值也为true。
如果我输入说出用户名,评估......
Request.Form["ApplicationUser.UserName"]
给出了正确的值,但我认为应该由Bind填充的ApplicationUser.UserName没有任何内容!?
我怀疑这是我的Bind声明,但我尝试了UserName,ApplicationUser.UserName和ApplicationUser_UserName,但似乎都有同样的问题。
这个问题来自我提出的另一个问题(链接如下),所以我错过了什么?
Entity Framework 6 Reusing Data Annotations
请注意,我对这个特定实现中的错误感兴趣,而不是出于各种原因提供替代实现,我真的不想进入。
答案 0 :(得分:1)
我已下载您的代码并将其包含在新的空MVC4应用程序中。
坏消息是它没有用。
好消息是它可以通过一个小小的变化完美地运作:
在你的控制器中,
Bind
POST操作参数Register
属性
[Bind(Include = "Account, ApplicationUser, Password, PasswordConfirmation")]
关于你的代码的一对评论:
Bind
属性。您宁愿使用所需的确切属性创建一个ViewModel(以这种方式键入和维护更少的代码!)。答案 1 :(得分:0)
尝试在RegisterViewModel中包含ApplicationUser和Account属性。
public class RegisterViewModel
{
[Display(Prompt = "Your Name", Name = "Contact Name"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Please enter a valid contact")]
public string ContactName { get; set; }
[Display(Name = "Username", Prompt = "Login As"), Required(), StringLength(255, MinimumLength = 3, ErrorMessage = "Your username must be at least 3 characters")]
public string UserName { get; set; }
[Display(Name = "Account Type", Prompt = "Account Type"), Required()]
public AccountType AccountType { get; set; }
[Display(Name = "Organisation Name", Prompt = "Name of Organisation"), StringLength(255)]
public string OrganisationName { get; set; }
public RegisterViewModel()
{
}
[Display(Name = "Password", Prompt = "Password"), Required(), DataType(DataType.Password), StringLength(255, MinimumLength = 5, ErrorMessage = "The password must be at least 7 characters")]
public string Password { get; set; }
[Display(Name = "Confirm Password", Prompt = "Confirm Password"), Compare("Password", ErrorMessage = "Your confirmation doesn't match...")]
public string PasswordConfirmation { get; set; }
}
答案 2 :(得分:0)
您可能想要删除构造函数(因为如果它们为null,则需要它们确定)
public RegisterViewModel()
{
ApplicationUser = new ApplicationUser();
Account = new Account();
}
并且需要ApplicationUser
和Account
属性。
验证在绑定期间发生,如果这两个属性都没有绑定,那么您的模型状态将在设计上有效。