I am developing an Asp.Net mvc application. In my project there are two forms in a single view like this:
To use multiple forms in a single view, there is a problem for validation using data annotation. First I found this link for using multiple forms in single view asp.net MVC 4 multiple post via different forms . Following answer of that link, I can add multiple forms. But I cannot validate using data annotation with that approach. So I googled for another solution.
This link ( http://geekswithblogs.net/MightyZot/archive/2013/11/11/html.validationsummary-and-multiple-forms.aspx ) also just the same, I have to add validation logic in controller. I found another solution ( http://bluetubeinc.com/blog/2012/10/validating-multiple-forms-the-asp-dot-net-mvc3-way-using-strongly-typed-views ). I thought this solution will solve my problem to validation using data annotation. But one thing to notice is that it is working with Ajax Form. But I followed that link and I am still having problem.
These are my view models:
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; }
}
This is my controller and actions for login and register:
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
}
}
This is my view:
<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")
}
But when I submit the form, model state is always invalid because values are always null even if I input correct values. For example, I login, then form will submit to post login action, but value are always null.
Why is that always null? How can I bind to get correct values? How can I validate multiple forms in a single view (strongly typed view) using data annotation?
As @stephen-muecke says doing this will work:
public async Task<ActionResult> Register([Bind(Prefix="RegisterForm")]RegisterViewModel model)
{
//check modelstate and continue
}
If you don't want to do that then you can create a partial view for each form and pass the model required for that form to that partial view.
<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-->
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.