以 ASP.NET 形式提交更改后的 FormData 以具有 ModelState 和重定向的正常行为
Submit changed FormData in ASP.NET form to have normal behavior with ModelState and redirections
我正在使用 APS.NET Core MVC (.NET 5.0) 开发网络应用程序。我有一个实体(服务),它有另一个实体(开放时间)的动态列表。所以一个服务可以有不同的开放时间,例如:
- 从08:00到20:00
- 从 08:00 到 13:00 和从 17:00 到 20:00
您可以根据需要设置不同的时间段。我不知道如何实施这种情况并寻找我找到的解决方案 and followed the 使其适应我的实体。稍微简化一下,代码如下:
模型(或视图模型):
public class Service
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public List<ServiceOpeningHours> OpeningHours { get; set; } = new List<ServiceOpeningHours>();
}
public class ServiceOpeningHours
{
public TimeSpan From { get; set; }
public TimeSpan To { get; set; }
}
Create.cshtml(查看):
@model MyWebApp.Services.Models.Service
...
<form asp-action="Create" name="createForm" id="createForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label class="control-label">Name</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Description</label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<fieldset>
<legend>Opening Hours</legend>
<div id="openingHoursContainer">
@foreach (ServiceOpeningHours item in Model.OpeningHours)
{
<partial name="_OpeningHourEditor" manifest model="item" />
}
</div>
</fieldset>
<div>
<div class="form-group">
<input id="addOpeningHourItem" type="button" value="Add Opening Hour" class="btn btn-primary" />
</div>
<div class="form-group">
<input type="submit" id="submit" value="Create" class="btn btn-primary" />
</div>
</div>
</form>
...
@section Scripts {
$('#addOpeningHourItem').click(function (event) {
event.preventDefault();
$.ajax({
async: true,
data: $('#form').serialize(),
type: 'POST',
url: '/Services/AddBlankOpeningHour',
success: function (partialView) {
$('#openingHoursContainer').append(partialView);
}
});
});
$('#submit').click(function (event) {
event.preventDefault();
var formData = new FormData();
formData.append("Name", $('input[name="Name"]').val());
formData.append("Description", $('input[name="Description"]').val());
$("input[name='From']").each(function (i) {
var from = $(this).val();
formData.append("OpeningHours[" + i + "].From", from);
});
$("input[name='To']").each(function (i) {
var to = $(this).val();
formData.append("OpeningHours[" + i + "].To", to);
});
formData.append("__RequestVerificationToken", $('form[name="createForm"] input[name="__RequestVerificationToken"]').val());
$.ajax({
method: 'POST',
url: '/Services/Create',
data: formData,
processData: false,
contentType: false,
success: function (returnValue) {
console.log('Success: ' + returnValue);
}
});
});
}
_OpeningHourEditor.cshtml(开放时间项目的部分视图):
@model MyWebApp.Models.ServiceOpeningHours
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">From</label>
<input asp-for="From" class="form-control" />
<span asp-validation-for="From" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label">To</label>
<input asp-for="To" class="form-control" />
<span asp-validation-for="To" class="text-danger"></span>
</div>
</div>
</div>
在 javascript 代码中创建了一个 FormData
并填充了所有字段,模型成功到达 Create
操作。
服务控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Service service)
{
if (ModelState.IsValid)
{
// Save data in data base...
return this.RedirectToAction("Index");
}
return View(service);
}
[HttpPost]
public ActionResult AddBlankOpeningHour()
{
return PartialView("_OpeningHourEditor", new ServiceOpeningHours());
}
使用此代码,当 Create
动作 returns 响应时,它到达 $.ajax()
的 success
块,但这不会导致页面重新加载使用新数据。
我认为你不应该用 AJAX 来做。我应该如何拨打电话才能使一切正常?也就是说,如果 Name
或 Description
字段未填写,则应显示 ModelState
错误消息,如果一切顺利,则应将其重定向到 Index
动作。
修改提交脚本以删除 ajax 并最初更改输入字段的名称,以便列表正确绑定到模型。
$('#submit').click(function (event) {
// initially prevent form submit
event.preventDefault();
// loop through all input with name From, and change their name with index
$("input[name='From']").each(function (i) {
$(this).attr("name", "OpeningHours[" + i + "].From");
});
// loop through all input with name To, and change their name with index
$("input[name='To']").each(function (i) {
$(this).attr("name", "OpeningHours[" + i + "].To");
});
// submit the form
$("#createForm").submit();
});
我正在使用 APS.NET Core MVC (.NET 5.0) 开发网络应用程序。我有一个实体(服务),它有另一个实体(开放时间)的动态列表。所以一个服务可以有不同的开放时间,例如:
- 从08:00到20:00
- 从 08:00 到 13:00 和从 17:00 到 20:00
您可以根据需要设置不同的时间段。我不知道如何实施这种情况并寻找我找到的解决方案
模型(或视图模型):
public class Service
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public List<ServiceOpeningHours> OpeningHours { get; set; } = new List<ServiceOpeningHours>();
}
public class ServiceOpeningHours
{
public TimeSpan From { get; set; }
public TimeSpan To { get; set; }
}
Create.cshtml(查看):
@model MyWebApp.Services.Models.Service
...
<form asp-action="Create" name="createForm" id="createForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label class="control-label">Name</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Description</label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<fieldset>
<legend>Opening Hours</legend>
<div id="openingHoursContainer">
@foreach (ServiceOpeningHours item in Model.OpeningHours)
{
<partial name="_OpeningHourEditor" manifest model="item" />
}
</div>
</fieldset>
<div>
<div class="form-group">
<input id="addOpeningHourItem" type="button" value="Add Opening Hour" class="btn btn-primary" />
</div>
<div class="form-group">
<input type="submit" id="submit" value="Create" class="btn btn-primary" />
</div>
</div>
</form>
...
@section Scripts {
$('#addOpeningHourItem').click(function (event) {
event.preventDefault();
$.ajax({
async: true,
data: $('#form').serialize(),
type: 'POST',
url: '/Services/AddBlankOpeningHour',
success: function (partialView) {
$('#openingHoursContainer').append(partialView);
}
});
});
$('#submit').click(function (event) {
event.preventDefault();
var formData = new FormData();
formData.append("Name", $('input[name="Name"]').val());
formData.append("Description", $('input[name="Description"]').val());
$("input[name='From']").each(function (i) {
var from = $(this).val();
formData.append("OpeningHours[" + i + "].From", from);
});
$("input[name='To']").each(function (i) {
var to = $(this).val();
formData.append("OpeningHours[" + i + "].To", to);
});
formData.append("__RequestVerificationToken", $('form[name="createForm"] input[name="__RequestVerificationToken"]').val());
$.ajax({
method: 'POST',
url: '/Services/Create',
data: formData,
processData: false,
contentType: false,
success: function (returnValue) {
console.log('Success: ' + returnValue);
}
});
});
}
_OpeningHourEditor.cshtml(开放时间项目的部分视图):
@model MyWebApp.Models.ServiceOpeningHours
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">From</label>
<input asp-for="From" class="form-control" />
<span asp-validation-for="From" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label">To</label>
<input asp-for="To" class="form-control" />
<span asp-validation-for="To" class="text-danger"></span>
</div>
</div>
</div>
在 javascript 代码中创建了一个 FormData
并填充了所有字段,模型成功到达 Create
操作。
服务控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Service service)
{
if (ModelState.IsValid)
{
// Save data in data base...
return this.RedirectToAction("Index");
}
return View(service);
}
[HttpPost]
public ActionResult AddBlankOpeningHour()
{
return PartialView("_OpeningHourEditor", new ServiceOpeningHours());
}
使用此代码,当 Create
动作 returns 响应时,它到达 $.ajax()
的 success
块,但这不会导致页面重新加载使用新数据。
我认为你不应该用 AJAX 来做。我应该如何拨打电话才能使一切正常?也就是说,如果 Name
或 Description
字段未填写,则应显示 ModelState
错误消息,如果一切顺利,则应将其重定向到 Index
动作。
修改提交脚本以删除 ajax 并最初更改输入字段的名称,以便列表正确绑定到模型。
$('#submit').click(function (event) {
// initially prevent form submit
event.preventDefault();
// loop through all input with name From, and change their name with index
$("input[name='From']").each(function (i) {
$(this).attr("name", "OpeningHours[" + i + "].From");
});
// loop through all input with name To, and change their name with index
$("input[name='To']").each(function (i) {
$(this).attr("name", "OpeningHours[" + i + "].To");
});
// submit the form
$("#createForm").submit();
});