我正在开发一个Asp.Net mvc应用程序。在我的项目中,在这样的单个视图中有两种形式。
要在单个视图中使用多个表单,使用数据批注进行验证时会出现问题。首先,我在单个视图asp.net MVC 4 multiple post via different forms中找到了使用多个表单的链接。在回答该链接后,我可以添加多个表单。但我无法使用该方法验证数据注释。所以我用Google搜索了另一种解决方案。
这个链接(http://geekswithblogs.net/MightyZot/archive/2013/11/11/html.validationsummary-and-multiple-forms.aspx)也一样,我必须在控制器中添加验证逻辑。我找到了另一个解决方案(http://bluetubeinc.com/blog/2012/10/validating-multiple-forms-the-asp-dot-net-mvc3-way-using-strongly-typed-views)。我认为这个解决方案将解决我使用数据注释进行验证的问题。但有一点需要注意的是它正在使用Ajax Form。但我遵循了这个链接,我仍然有问题。
这些是我的观点模型
public class AuthVM
{
public LoginViewModel LoginForm { get; set; }
public RegisterViewModel RegisterForm { get; set; }
}
public class LoginViewModel
{
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
}
public class RegisterViewModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[MaxLength(70)]
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; }
}
这是我的控制器和登录和注册的行动
public class AccountController: Controller
{
[AllowAnonymous]
public ActionResult Create(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
AuthVM model = new AuthVM
{
RegisterForm = new RegisterViewModel(),
LoginForm = new LoginViewModel()
};
return View("Auth",model);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
//check modelstate and continue
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
//check modelstate and continue
}
}
这是我的观点
<section id="form">
<!--form-->
<div class="container">
<div class="row">
<div class="col-sm-4 col-sm-offset-1">
<div class="login-form">
<!--login form-->
<h2>Login to your account</h2>
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, null))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.TextBoxFor(x => x.LoginForm.Email, new { placeholder = "Email" })
@Html.PasswordFor(x => x.LoginForm.Password, new { placeholder = "Password" })
<button type="submit" class="btn btn-default">Login</button>
}
</div><!--/login form-->
</div>
<div class="col-sm-1">
<h2 class="or">OR</h2>
</div>
<div class="col-sm-4">
<div class="signup-form">
<!--sign up form-->
<h2>New User Signup!</h2>
@using (Html.BeginForm("Register", "Account", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.TextBoxFor(x => x.RegisterForm.UserName, new { placeholder = "Display Name" })
@Html.TextBoxFor(x => x.RegisterForm.Email, new { placeholder = "Email" })
@Html.PasswordFor(x => x.RegisterForm.Password, new { placeholder = "Password" })
@Html.PasswordFor(x => x.RegisterForm.ConfirmPassword, new { placeholder = "Retype password" })
<button class="btn btn-primary">Register</button>
}
</div><!--/sign up form-->
</div>
</div>
</div>
</section><!--/form-->
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
但是当我提交表单时,模型状态始终无效,因为即使输入正确的值,值也始终为null。例如,我登录,然后表单将提交到发布登录操作,但值始终为空。
为什么总是空?如何绑定以获取正确的值?如何使用数据注释在单个视图(强类型视图)中验证多个表单?
答案 0 :(得分:1)
就像@ stephen-muecke所说的那样,可以这样做:
public async Task<ActionResult> Register([Bind(Prefix="RegisterForm")]RegisterViewModel model)
{
//check modelstate and continue
}
如果您不想这样做,则可以为每个表单创建一个局部视图,并将该表单所需的模型传递给该局部视图。
<section id="form">
<!--form-->
<div class="container">
<div class="row">
<div class="col-sm-4 col-sm-offset-1">
<div class="login->
@Html.Partial("_LoginForm", Model.LoginForm)
</div><!--/login form-->
</div>
<div class="col-sm-1">
<h2 class="or">OR</h2>
</div>
<div class="col-sm-4">
<div class="signup-form">
@Html.Partial("_RegisterForm", Model.RegisterForm)
</div><!--/sign up form-->
</div>
</div>
</div>
</section><!--/form-->