当 ModelState.IsValid = false 重定向时模态弹出窗口显示不正确
Modal Pop-Up Displaying Incorrectly When ModelState.IsValid = false Redirect
我的模式弹出窗口在 HttpPost 上的模型验证失败时显示不正确时遇到了问题。当模态 returns 数据验证失败时,我希望屏幕 return 将模态弹出窗口作为弹出窗口显示在最初生成弹出窗口的屏幕上。令人高兴的是弹出窗口填满了整个屏幕,没有任何格式(即此时它不是模态弹出窗口)。它确实显示了验证消息,就像未格式化的文本一样。以下是我使用的所有代码片段:
这是我的 site.js
(function () {
// Initialize numeric spinner input boxes
//$(".numeric-spinner").spinedit();
// Initialize modal dialog
// attach modal-container bootstrap attributes to links with .modal-link class.
// when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
// Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears
$('body').on('click', '.modal-close-btn', function () {
$('#modal-container').modal('hide');
});
//clear modal cache, so that new content can be loaded
$('#modal-container').on('hidden.bs.modal', function () {
$(this).removeData('bs.modal');
});
$('#CancelModal').on('click', function () {
return false;
});
});
我是这样调用弹出窗口的:
<div id="modal-container" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-content"></div>
</div>
<a href="@Url.Action("CreateEdit", new { controller = "Issue", issueid = Model.IssueData.issueId, addedit = "add" })" class="modal-link btn btn-success">Add New Status</a>
这是处理来自模态弹出窗口的 HttpPost 的控制器
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult CreateEdit(StatusViewModel model)
{
if (ModelState.IsValid)
{
//Do Stuff
return RedirectToAction("edit");
} else
{
return PartialView("_CreateEdit", model);
}
}
这是模态弹出窗口:
@model MYAPP.ViewModels.StatusViewModel
<!--Modal Body Start-->
<div class="modal-content">
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">@ViewBag.Title</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="CreateEdit" asp-controller="Issue" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div class="form-group row">
@Html.HiddenFor(model => model.addedit)
@Html.HiddenFor(model => model.IssueID)
@Html.HiddenFor(model => model.StatusDate)
@Html.LabelFor(model => model.Status, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.Status" class="form-control" rows="10" placeholder="Enter/Update Status">@Model.Status</textarea>
</div>
</div>
<div class="form-group row">
@Html.LabelFor(model => model.NextStep, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.NextStep" class="form-control" rows="10" placeholder="Please enter the next steps here">@Model.NextStep</textarea>
</div>
</div>
<div class="form-group">
<label asp-for="@Model.ColorCode" class="control-label"></label>
@Html.DropDownListFor(modelItem => modelItem.ColorCode, new[] {
new SelectListItem { Text = " ", Value = "" },
new SelectListItem { Text = "Red", Value = "R" },
new SelectListItem { Text = "Yellow", Value = "Y" },
new SelectListItem { Text = "Green", Value = "G" } })
<span asp-validation-for="@Model.ColorCode" class="text-danger"></span>
</div>
<div>
<table class="statustable">
<tr class="statustablerow">
<th></th>
<th>Previous Status</th>
<th>Previous Next Steps</th>
</tr>
<tr class="statustabledata">
@if (@ViewBag.LastColorCode == "R")
{
<td rowspan="2" width="2%" style=" background-color:red"></td>
}
else if (@ViewBag.LastColorCode == "Y")
{
<td rowspan="2" width="2%" style="background-color: yellow"></td>
}
else if (@ViewBag.LastColorCode == "G")
{
<td rowspan="2" width="2%" style="background-color: green"></td>
}
else
{
<td rowspan="2" width="2%" style="background-color: gray"></td>
}
<td width="20%">Previous Status:</td>
<td width="78%">@ViewBag.LastStatus</td>
</tr>
<tr class="statustabledata">
<td>Previous Next Steps:</td>
<td>@ViewBag.LastNextSteps</td>
</tr>
</table>
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<button class="btn btn-success relative" id="btnSubmit" data-save="modal">
<i class="loader"></i>
Submit
</button>
</div>
<div class="row">
</div>
<!--Modal Footer End-->
</form>
</div>
<script type="text/javascript">
$(function () {
});
</script>
<!--Modal Body End-->
当验证失败时,如何让屏幕恢复显示带有弹出窗口的页面?
你应该通过ajax提交表单,并将模态替换为return编辑的数据(局部视图的html),否则会直接return部分视图作为新视图。
我对你的代码做了一些修改,你可以参考下面的例子:
型号:
public class StatusViewModel
{
public string addedit { get; set; }
public int IssueID { get; set; }
public DateTime StatusDate { get; set; }
[Required]
public string Status { get; set; }
[Required]
public string NextStep { get; set; }
[Required]
public string ColorCode { get; set; }
}
Edit.cshtml:
<div id="modal-container" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
</div>
</div>
</div>
<a href="@Url.Action("CreateEdit", new { controller = "Issue", issueid = "1", addedit = "add" })" class="modal-link btn btn-success">Add New Status</a>
@section scripts{
<script>
$('body').on('click', '.modal-link', function () {
var actionUrl = $(this).attr('href');
$.get(actionUrl).done(function (data) {
$('body').find('.modal-content').html(data);
});
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
$('body').on('click', '.relative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$('body').find('.modal-content').html(data);
});
})
$('body').on('click', '.close', function () {
$('body').find('#modal-container').modal('hide');
});
$('#CancelModal').on('click', function () {
return false;
});
</script>
}
_创建Edit.cshtml:
@model StatusViewModel
<!--Modal Body Start-->
@{
ViewBag.Title = "Edit";
}
<div class="modal-header">
<h4 class="modal-title">@ViewBag.Title</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body form-horizontal">
<form asp-action="CreateEdit" asp-controller="Issue" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="form-group row">
@Html.HiddenFor(model => model.addedit)
@Html.HiddenFor(model => model.IssueID)
@Html.HiddenFor(model => model.StatusDate)
@Html.LabelFor(model => model.Status, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.Status" class="form-control" rows="10" placeholder="Enter/Update Status">@Model.Status</textarea>
<span asp-validation-for="@Model.Status" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
@Html.LabelFor(model => model.NextStep, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.NextStep" class="form-control" rows="10" placeholder="Please enter the next steps here">@Model.NextStep</textarea>
<span asp-validation-for="@Model.NextStep" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="@Model.ColorCode" class="control-label"></label>
@Html.DropDownListFor(modelItem => modelItem.ColorCode, new[] {
new SelectListItem { Text = " ", Value = "" },
new SelectListItem { Text = "Red", Value = "R" },
new SelectListItem { Text = "Yellow", Value = "Y" },
new SelectListItem { Text = "Green", Value = "G" } })
<span asp-validation-for="@Model.ColorCode" class="text-danger"></span>
</div>
<div>
<table class="statustable">
<tr class="statustablerow">
<th></th>
<th>Previous Status</th>
<th>Previous Next Steps</th>
</tr>
<tr class="statustabledata">
@if (@ViewBag.LastColorCode == "R")
{
<td rowspan="2" width="2%" style=" background-color:red"></td>
}
else if (@ViewBag.LastColorCode == "Y")
{
<td rowspan="2" width="2%" style="background-color: yellow"></td>
}
else if (@ViewBag.LastColorCode == "G")
{
<td rowspan="2" width="2%" style="background-color: green"></td>
}
else
{
<td rowspan="2" width="2%" style="background-color: gray"></td>
}
<td width="20%">Previous Status:</td>
<td width="78%">@ViewBag.LastStatus</td>
</tr>
<tr class="statustabledata">
<td>Previous Next Steps:</td>
<td>@ViewBag.LastNextSteps</td>
</tr>
</table>
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success relative" id="btnSubmit" data-save="modal" value="Submit">
</div>
<div class="row">
</div>
</form>
</div>
控制器:
public IActionResult Edit()
{
return View();
}
[HttpGet]
public ActionResult CreateEdit(int issueid, string addedit)
{
var model = new StatusViewModel
{
Status = "AAAAA",
NextStep = "BBBBB"
};
ViewBag.LastColorCode = "R";
ViewBag.LastStatus = "CCCC";
ViewBag.LastNextSteps = "DDDD";
return PartialView("_CreateEdit", model);
}
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult CreateEdit(StatusViewModel model)
{
if (ModelState.IsValid)
{
//Do Stuff
return RedirectToAction("edit");
}
else
{
return PartialView("_CreateEdit", model);
}
}
结果:
我的模式弹出窗口在 HttpPost 上的模型验证失败时显示不正确时遇到了问题。当模态 returns 数据验证失败时,我希望屏幕 return 将模态弹出窗口作为弹出窗口显示在最初生成弹出窗口的屏幕上。令人高兴的是弹出窗口填满了整个屏幕,没有任何格式(即此时它不是模态弹出窗口)。它确实显示了验证消息,就像未格式化的文本一样。以下是我使用的所有代码片段:
这是我的 site.js
(function () {
// Initialize numeric spinner input boxes
//$(".numeric-spinner").spinedit();
// Initialize modal dialog
// attach modal-container bootstrap attributes to links with .modal-link class.
// when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
// Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears
$('body').on('click', '.modal-close-btn', function () {
$('#modal-container').modal('hide');
});
//clear modal cache, so that new content can be loaded
$('#modal-container').on('hidden.bs.modal', function () {
$(this).removeData('bs.modal');
});
$('#CancelModal').on('click', function () {
return false;
});
});
我是这样调用弹出窗口的:
<div id="modal-container" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-content"></div>
</div>
<a href="@Url.Action("CreateEdit", new { controller = "Issue", issueid = Model.IssueData.issueId, addedit = "add" })" class="modal-link btn btn-success">Add New Status</a>
这是处理来自模态弹出窗口的 HttpPost 的控制器
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult CreateEdit(StatusViewModel model)
{
if (ModelState.IsValid)
{
//Do Stuff
return RedirectToAction("edit");
} else
{
return PartialView("_CreateEdit", model);
}
}
这是模态弹出窗口:
@model MYAPP.ViewModels.StatusViewModel
<!--Modal Body Start-->
<div class="modal-content">
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">@ViewBag.Title</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="CreateEdit" asp-controller="Issue" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div class="form-group row">
@Html.HiddenFor(model => model.addedit)
@Html.HiddenFor(model => model.IssueID)
@Html.HiddenFor(model => model.StatusDate)
@Html.LabelFor(model => model.Status, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.Status" class="form-control" rows="10" placeholder="Enter/Update Status">@Model.Status</textarea>
</div>
</div>
<div class="form-group row">
@Html.LabelFor(model => model.NextStep, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.NextStep" class="form-control" rows="10" placeholder="Please enter the next steps here">@Model.NextStep</textarea>
</div>
</div>
<div class="form-group">
<label asp-for="@Model.ColorCode" class="control-label"></label>
@Html.DropDownListFor(modelItem => modelItem.ColorCode, new[] {
new SelectListItem { Text = " ", Value = "" },
new SelectListItem { Text = "Red", Value = "R" },
new SelectListItem { Text = "Yellow", Value = "Y" },
new SelectListItem { Text = "Green", Value = "G" } })
<span asp-validation-for="@Model.ColorCode" class="text-danger"></span>
</div>
<div>
<table class="statustable">
<tr class="statustablerow">
<th></th>
<th>Previous Status</th>
<th>Previous Next Steps</th>
</tr>
<tr class="statustabledata">
@if (@ViewBag.LastColorCode == "R")
{
<td rowspan="2" width="2%" style=" background-color:red"></td>
}
else if (@ViewBag.LastColorCode == "Y")
{
<td rowspan="2" width="2%" style="background-color: yellow"></td>
}
else if (@ViewBag.LastColorCode == "G")
{
<td rowspan="2" width="2%" style="background-color: green"></td>
}
else
{
<td rowspan="2" width="2%" style="background-color: gray"></td>
}
<td width="20%">Previous Status:</td>
<td width="78%">@ViewBag.LastStatus</td>
</tr>
<tr class="statustabledata">
<td>Previous Next Steps:</td>
<td>@ViewBag.LastNextSteps</td>
</tr>
</table>
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<button class="btn btn-success relative" id="btnSubmit" data-save="modal">
<i class="loader"></i>
Submit
</button>
</div>
<div class="row">
</div>
<!--Modal Footer End-->
</form>
</div>
<script type="text/javascript">
$(function () {
});
</script>
<!--Modal Body End-->
当验证失败时,如何让屏幕恢复显示带有弹出窗口的页面?
你应该通过ajax提交表单,并将模态替换为return编辑的数据(局部视图的html),否则会直接return部分视图作为新视图。
我对你的代码做了一些修改,你可以参考下面的例子:
型号:
public class StatusViewModel
{
public string addedit { get; set; }
public int IssueID { get; set; }
public DateTime StatusDate { get; set; }
[Required]
public string Status { get; set; }
[Required]
public string NextStep { get; set; }
[Required]
public string ColorCode { get; set; }
}
Edit.cshtml:
<div id="modal-container" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
</div>
</div>
</div>
<a href="@Url.Action("CreateEdit", new { controller = "Issue", issueid = "1", addedit = "add" })" class="modal-link btn btn-success">Add New Status</a>
@section scripts{
<script>
$('body').on('click', '.modal-link', function () {
var actionUrl = $(this).attr('href');
$.get(actionUrl).done(function (data) {
$('body').find('.modal-content').html(data);
});
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
$('body').on('click', '.relative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$('body').find('.modal-content').html(data);
});
})
$('body').on('click', '.close', function () {
$('body').find('#modal-container').modal('hide');
});
$('#CancelModal').on('click', function () {
return false;
});
</script>
}
_创建Edit.cshtml:
@model StatusViewModel
<!--Modal Body Start-->
@{
ViewBag.Title = "Edit";
}
<div class="modal-header">
<h4 class="modal-title">@ViewBag.Title</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body form-horizontal">
<form asp-action="CreateEdit" asp-controller="Issue" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="form-group row">
@Html.HiddenFor(model => model.addedit)
@Html.HiddenFor(model => model.IssueID)
@Html.HiddenFor(model => model.StatusDate)
@Html.LabelFor(model => model.Status, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.Status" class="form-control" rows="10" placeholder="Enter/Update Status">@Model.Status</textarea>
<span asp-validation-for="@Model.Status" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
@Html.LabelFor(model => model.NextStep, new { @class = "col-sm-2 col-form-label" })
<div class="col-sm-10">
<textarea asp-for="@Model.NextStep" class="form-control" rows="10" placeholder="Please enter the next steps here">@Model.NextStep</textarea>
<span asp-validation-for="@Model.NextStep" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="@Model.ColorCode" class="control-label"></label>
@Html.DropDownListFor(modelItem => modelItem.ColorCode, new[] {
new SelectListItem { Text = " ", Value = "" },
new SelectListItem { Text = "Red", Value = "R" },
new SelectListItem { Text = "Yellow", Value = "Y" },
new SelectListItem { Text = "Green", Value = "G" } })
<span asp-validation-for="@Model.ColorCode" class="text-danger"></span>
</div>
<div>
<table class="statustable">
<tr class="statustablerow">
<th></th>
<th>Previous Status</th>
<th>Previous Next Steps</th>
</tr>
<tr class="statustabledata">
@if (@ViewBag.LastColorCode == "R")
{
<td rowspan="2" width="2%" style=" background-color:red"></td>
}
else if (@ViewBag.LastColorCode == "Y")
{
<td rowspan="2" width="2%" style="background-color: yellow"></td>
}
else if (@ViewBag.LastColorCode == "G")
{
<td rowspan="2" width="2%" style="background-color: green"></td>
}
else
{
<td rowspan="2" width="2%" style="background-color: gray"></td>
}
<td width="20%">Previous Status:</td>
<td width="78%">@ViewBag.LastStatus</td>
</tr>
<tr class="statustabledata">
<td>Previous Next Steps:</td>
<td>@ViewBag.LastNextSteps</td>
</tr>
</table>
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success relative" id="btnSubmit" data-save="modal" value="Submit">
</div>
<div class="row">
</div>
</form>
</div>
控制器:
public IActionResult Edit()
{
return View();
}
[HttpGet]
public ActionResult CreateEdit(int issueid, string addedit)
{
var model = new StatusViewModel
{
Status = "AAAAA",
NextStep = "BBBBB"
};
ViewBag.LastColorCode = "R";
ViewBag.LastStatus = "CCCC";
ViewBag.LastNextSteps = "DDDD";
return PartialView("_CreateEdit", model);
}
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult CreateEdit(StatusViewModel model)
{
if (ModelState.IsValid)
{
//Do Stuff
return RedirectToAction("edit");
}
else
{
return PartialView("_CreateEdit", model);
}
}
结果: