MVC Bootstrap PopOver с проверкой на стороне сервера
У меня есть простое приложение MVC, которое отображает BootStrap PopOver Modal с формой на нем. Я хотел бы выполнить некоторую проверку на стороне сервера по форме, когда данные передаются. Если обнаружена ошибка, я хотел бы, чтобы приложение оставляло существующую форму открытой с данными пользователя на месте при отображении любых ошибок, сохраненных в ModelState.
Когда я вызываю представление "Создать" непосредственно в этом приложении, форма отображает ошибки соответствующим образом. Однако, когда я использую представление Create как модальное, оно показывает сообщение об ошибке, заявляющее, что были ошибки проверки, но ValidationSummary не отображает подробности ошибки.
Как я могу получить данные из ModelState обратно в представление?
Модели /MyViewModel.cs
public class MyViewModel
{
[Display(Name = "Field #1")]
public string Field1 { get; set; }
[Required(ErrorMessage = "Field2 is required.")]
[StringLength(10)]
[Display(Name = "Field #2")]
public string Field2 { get; set; }
}
Контроллеры / HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Create()
{
var data = new MyViewModel {Field1 = "This is field 1!"};
return PartialView("Create", data);
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
if (!ModelState.IsValid)
{
// There were validation errors. Don't lose the data the user entered on the page.
// Do I need to return the modelstate here?
return PartialView(model);
}
return Json(new { success = true });
}
}
Views / Home / Index.chstml
@Html.ActionLink("Open the popover modal", "create", null, null, new { id = "modalLink" })
@Html.ActionLink("Navigate directly to the modal page", "Create", "Home")
<script type="text/javascript">
$(function () {
$('#modalLink').click(function () {
$('#dialog').load(this.href, function () {
$('#simpleModal').modal('show');
bindForm(this);
});
return false;
});
});
function bindForm(dialog) {
$('form', dialog).submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
alert('Validation was successful.');
$('#simpleModal').modal('hide');
} else {
// Am I missing something here?
alert('Server validation failed!');
}
}
});
return false;
});
}
</script>
Views / Home / Create.cshtml
@model MvcModalPopupWithValidation.Models.MyViewModel
@using (Html.BeginForm())
{
<div class="modal fade" id="simpleModal" tabindex="-1" role="dialog" aria-labelledby="simpleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="simpleModalLabel">
Modal Validation Test
</h4>
</div>
<div class="modal-body">
@Html.ValidationSummary(true)
<div>
@Html.LabelFor(x => x.Field1)
@Html.EditorFor(x => x.Field1)
@Html.ValidationMessageFor(x => x.Field1)
</div>
<div>
@Html.LabelFor(x => x.Field2)
@Html.EditorFor(x => x.Field2)
@Html.ValidationMessageFor(x => x.Field2)
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" id="btnDeclineModal">Save changes</button>
</div>
</div>
</div>
</div>
}
1 ответ
Мне удалось заставить серверную проверку работать. Я все еще надеюсь, что кто-то может найти правильный, лучший или автоматический способ сделать это.
Если у кого-то возникли те же трудности, что и у меня, вот изменения кода, которые я должен был сделать, чтобы заставить его работать должным образом.
Изменения контроллера
[HttpPost]
public ActionResult Create(MyViewModel model)
{
if (!ModelState.IsValid)
{
var errors = new List<string>();
foreach (var modelState in ViewData.ModelState.Values)
{
errors.AddRange(modelState.Errors.Select(error => error.ErrorMessage));
}
return Json(errors);
}
return Json(new { success = true });
}
Create.cshtml Changes
<div id="errorContainer" class="alert alert-danger" style="display: none">
Validation issues:
<div id="errors"></div>
</div>
Index.cshtml Изменения
function bindForm(dialog) {
$('form', dialog).submit(function () {
$.ajax({
url: this.action,
type: this.method,
//traditional: true,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
showValidationErrors(false);
$('#simpleModal').modal('hide');
alert('Validation was successful.');
} else {
fillErrorList(result);
showValidationErrors(true);
}
}
});
return false;
});
function showValidationErrors(isShown) {
if (isShown) {
$("#errorContainer").show();
} else {
$("#errorContainer").hide();
}
}
function fillErrorList(errors) {
$("#errors").html("");
var list = document.createElement('ul');
for (var i = 0; i < errors.length; i++) {
var item = document.createElement('li');
item.appendChild(document.createTextNode(errors[i]));
list.appendChild(item);
}
$("#errors").html(list);
}