I have a PartialView that contains a form that asynchronously posts data to my controller. The controller will add the user if the ModelState
is valid, if not, it will return the PartialView with the invalid model. The problem I'm running into is that the ModelState
is always valid no matter what. I can see that the form is being serialized properly and all the properties for DynamicActionUserModel.RegisterModel
are being populated.
I don't understand why this would be the case but is it possible the Model Binding isn't working because I have a model within a model?
Here's my code...
View
@model IEnumerable<RobotDog.Models.UserModel>
<!-- other stuff -->
<div class="createUser">
@Html.Partial("_UserPartial", new DynamicActionUserModel { Action = "CreateUser", RegisterModel = new RegisterModel() })
</div>
<script type="text/javascript">
$(function () {
$('form.ajax').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
location.reload(true);
} else {
$('.createUser').html(result);
}
}
});
}
return false;
});
});
</script>
_UserPartial View
@model RobotDog.Models.DynamicActionUserModel
@using(Html.BeginForm(Model.Action,"Admin", FormMethod.Post, new { @class = "ajax" })) {
@Html.ValidationSummary(true, "Registration unsuccessful. Please correct errors and try again.")
@Html.TextBoxFor(x => x.RegisterModel.Email, new { @class = "input-xlarge", @placeholder = "Email"})
@Html.TextBoxFor(x => x.RegisterModel.UserName, new { @class = "input-xlarge", @placeholder = "User Name"})
@Html.PasswordFor(x => x.RegisterModel.Password, new { @class = "input-xlarge", @placeholder = "Password"})
@Html.ListBoxFor(x => x.RegisterModel.SelectedRoles, Model.RegisterModel.Roles)
<input type="submit" value="Submit" class="btn"/>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
DynamicActionUserModel
public class DynamicActionUserModel {
public string Action { get; set; }
public RegisterModel RegisterModel { get; set; }
}
public class RegisterModel {
[Required(AllowEmptyStrings = false)]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
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; }
public string[] SelectedRoles { get; set; }
public MultiSelectList Roles {
get { return new MultiSelectList(System.Web.Security.Roles.GetAllRoles()); }
}
}
Controller
[HttpPost]
public ActionResult CreateUser(DynamicActionUserModel model) {
if (!ModelState.IsValid) {
foreach(var value in ModelState.Values) {
foreach (var error in value.Errors) {
ModelState.AddModelError(string.Empty, error.ErrorMessage);
}
}
return PartialView("_UserPartial", model);
}
try {
...
return Json(new { success = true });
}
catch(Exception e) { ... }
return PartialView("_UserPartial", model);
}