Asp.Net 核心 通过 Ajax 提交表单时获得 500 状态。没有 Ajax 也能完美运行
Asp.Net Core Getting a 500 status when submitting a form through Ajax. Works perfectly without Ajax
我有一个非常简单的表单 - 只有三个字段,其中只有两个由用户通过下拉菜单填写。第三个自动标记为 DateTime.Now。我使用了一些我已经为其他表单准备好的脚手架中的表单提交代码。当我将该代码放入 Home 控制器(显然是在更改了一些代码之后)并构建了表单时,一切都很好。所以我知道我的关系和路径都很好。
但是,提交后,它刷新了整个页面。我不能那样。它只需要刷新页面上的特定 div。所以,我必须运行它通过Ajax。这是我头发掉了一半的地方...
当我记录通过 Ajax 传递的值时,正在获取正确的值,但随后我收到“Home/CreateBreak”的 500 错误,这正是它所在的位置在控制器中。这是控制台在 Chrome 中的所有代码和屏幕截图。提前感谢您的帮助。
Home Controller:(创建条目时只填写TimeEntered、EmployeeId和EmpPosition)
//Create//
[HttpPost]
public async Task<IActionResult> CreateBreak([Bind("Id,TimeEntered,TimeCleared,EmpSent,EmployeeId,EmpPosition,RlfPosition")] Break newBreak)
{
if (ModelState.IsValid)
{
newBreak.TimeEntered = DateTime.Now;
_context.Add(newBreak);
await _context.SaveChangesAsync();
return Json(new { success = true, });
}
else
{
return Json(new { success = false });
}
}
Ajax:
//Add Break
$(document).on("click", "#break_submit", function () {
var model = {};
model.EmployeeId = Number($("#EmpId").val());
model.EmpPosition = Number($("#EmployeePosition").val());
console.log("model", model);
$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
data: JSON.stringify(model),
success: function (data) {
if (data.success)
{
$(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
$(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
}
else
alert("Error: Please enter your name AND position");
},
error: function () {
alert("Error: Please enter your name AND position");
}
});
});
表格:
@model Seating.ViewModels.ListsVM
<form id="ajax_submit" class="DthdropdownGroup ml-3">
<div class="btn-group" style="margin-left:-1rem">
<select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.4em;" id="EmpId">
<option disabled selected>Dispatcher</option>
@foreach (var item in Model.Employees)
{
<option class="dropdown-item pr-1 form-control" value="@item.Id">@item.DisplayName</option>
}
</select>
</div>
<div class="btn-group">
<select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.3em" id="EmployeePosition">
<option disabled selected>Position</option>
@foreach (var item in Model.Positions)
{
<option class="dropdown-item pr-1" value="@item.Id">@item.PositionName</option>
}
</select>
</div>
<button type="button" class="btn btn-sm btn-block dropdownStyling" id="break_submit" style="margin-left: -1rem; width:15rem;">Submit</button>
</form>
填充下拉列表的 VM(适用于所有表单 - 不仅仅是这个):
namespace Seating.ViewModels
{
public class ListsVM
{
public ListsVM()
{
Employees = new List<Employee>();
Positions = new List<Position>();
}
public IEnumerable<Dth> Dths { get; set; }
public IEnumerable<Break> Breaks { get; set; }
public IEnumerable<Lunch> Lunches { get; set; }
public IEnumerable<Employee> Employees { get; set; }
public IEnumerable<Position> Positions { get; set; }
public int EmployeeId { get; set; }
public int EmpPosition { get; set; }
public bool EmpSent { get; set; }
public bool LunchTime { get; set; }
public bool LongerLunch { get; set; }
public bool DblLunch { get; set; }
}
}
还有,截图。您可以看到日志显示 Employee Id 3 和 Position 3 - 这很完美。但随后它会感到困惑,无法弄清楚从那里去哪里 - 即使我告诉它确切去哪里。
再次感谢
来自 ASP.NET 的 500 可能意味着在处理请求时在某个时刻抛出了未处理的异常。
我建议您将调试器附加到网络服务器进程
如果您也 double-checked 认为 URL 是正确的,那将会有所帮助。
你有一个错误,因为你的动作输入参数是空的。从 ajax
中删除 JSON.stringify(模型)
$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
data: model,
success: function (data) {
.....
或者如果你想使用 json 然后添加 contentType: application/json
$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(model),
success: function (data) {
...
并将 [FromBody] 添加到动作中
public async Task<IActionResult> CreateBreak([FromBody] Break newBreak)
恕我直言,您使用 Model
结构不必要地使 Controller
方法复杂化。由于您只需要将 EmployeeId
和 EmpPosition
变量发送到 Controller
方法,您可以这样做:
//Add Break
$(document).on("click", "#break_submit", function () {
var EmployeeId = Number($("#EmpId").val());
var EmpPosition = Number($("#EmployeePosition").val());
var json = {
EmployeeId: EmployeeId,
EmpPosition: EmpPosition
};
console.log("Model", json);
$.ajax({
type: "post",
//url: "/Home/CreateBreak",
url: "@Url.Action("CreateBreak", "Home")",
dataType: "json",
data: {"json": JSON.stringify(json)},
success: function (data) {
if (data.success)
{
$(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
$(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
}
else
alert("Error: Please enter your name AND position");
},
error: function () {
alert("Error: Please enter your name AND position");
}
});
});
您的 Controller
方法将如下所示:
//Create//
[HttpPost]
public async Task<IActionResult> CreateBreak(string json)
{
Break newBreak=new Break();
int EmployeeId=0;
int EmpPosition=0;
if(!string.IsNullOrEmpty(json))
{
var jsonData = JsonConvert.DeserializeObject<dynamic>(json);
EmployeeId = Convert.ToInt32(jsonData.EmployeeId);
EmpPosition = Convert.ToInt32(jsonData.EmpPosition);
newBreak.EmployeeId = EmployeeId;
newBreak.EmpPosition = EmpPosition;
if (ModelState.IsValid)
{
newBreak.TimeEntered = DateTime.Now;
_context.Add(newBreak);
await _context.SaveChangesAsync();
return Json(new { success = true, });
}
else
{
return Json(new { success = false });
}
}
else
{
return Json(new { success = false });
}
}
我有一个非常简单的表单 - 只有三个字段,其中只有两个由用户通过下拉菜单填写。第三个自动标记为 DateTime.Now。我使用了一些我已经为其他表单准备好的脚手架中的表单提交代码。当我将该代码放入 Home 控制器(显然是在更改了一些代码之后)并构建了表单时,一切都很好。所以我知道我的关系和路径都很好。
但是,提交后,它刷新了整个页面。我不能那样。它只需要刷新页面上的特定 div。所以,我必须运行它通过Ajax。这是我头发掉了一半的地方...
当我记录通过 Ajax 传递的值时,正在获取正确的值,但随后我收到“Home/CreateBreak”的 500 错误,这正是它所在的位置在控制器中。这是控制台在 Chrome 中的所有代码和屏幕截图。提前感谢您的帮助。
Home Controller:(创建条目时只填写TimeEntered、EmployeeId和EmpPosition)
//Create//
[HttpPost]
public async Task<IActionResult> CreateBreak([Bind("Id,TimeEntered,TimeCleared,EmpSent,EmployeeId,EmpPosition,RlfPosition")] Break newBreak)
{
if (ModelState.IsValid)
{
newBreak.TimeEntered = DateTime.Now;
_context.Add(newBreak);
await _context.SaveChangesAsync();
return Json(new { success = true, });
}
else
{
return Json(new { success = false });
}
}
Ajax:
//Add Break
$(document).on("click", "#break_submit", function () {
var model = {};
model.EmployeeId = Number($("#EmpId").val());
model.EmpPosition = Number($("#EmployeePosition").val());
console.log("model", model);
$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
data: JSON.stringify(model),
success: function (data) {
if (data.success)
{
$(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
$(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
}
else
alert("Error: Please enter your name AND position");
},
error: function () {
alert("Error: Please enter your name AND position");
}
});
});
表格:
@model Seating.ViewModels.ListsVM
<form id="ajax_submit" class="DthdropdownGroup ml-3">
<div class="btn-group" style="margin-left:-1rem">
<select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.4em;" id="EmpId">
<option disabled selected>Dispatcher</option>
@foreach (var item in Model.Employees)
{
<option class="dropdown-item pr-1 form-control" value="@item.Id">@item.DisplayName</option>
}
</select>
</div>
<div class="btn-group">
<select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.3em" id="EmployeePosition">
<option disabled selected>Position</option>
@foreach (var item in Model.Positions)
{
<option class="dropdown-item pr-1" value="@item.Id">@item.PositionName</option>
}
</select>
</div>
<button type="button" class="btn btn-sm btn-block dropdownStyling" id="break_submit" style="margin-left: -1rem; width:15rem;">Submit</button>
</form>
填充下拉列表的 VM(适用于所有表单 - 不仅仅是这个):
namespace Seating.ViewModels
{
public class ListsVM
{
public ListsVM()
{
Employees = new List<Employee>();
Positions = new List<Position>();
}
public IEnumerable<Dth> Dths { get; set; }
public IEnumerable<Break> Breaks { get; set; }
public IEnumerable<Lunch> Lunches { get; set; }
public IEnumerable<Employee> Employees { get; set; }
public IEnumerable<Position> Positions { get; set; }
public int EmployeeId { get; set; }
public int EmpPosition { get; set; }
public bool EmpSent { get; set; }
public bool LunchTime { get; set; }
public bool LongerLunch { get; set; }
public bool DblLunch { get; set; }
}
}
还有,截图。您可以看到日志显示 Employee Id 3 和 Position 3 - 这很完美。但随后它会感到困惑,无法弄清楚从那里去哪里 - 即使我告诉它确切去哪里。
再次感谢
来自 ASP.NET 的 500 可能意味着在处理请求时在某个时刻抛出了未处理的异常。 我建议您将调试器附加到网络服务器进程 如果您也 double-checked 认为 URL 是正确的,那将会有所帮助。
你有一个错误,因为你的动作输入参数是空的。从 ajax
中删除 JSON.stringify(模型)$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
data: model,
success: function (data) {
.....
或者如果你想使用 json 然后添加 contentType: application/json
$.ajax({
type: "Post",
url: "/Home/CreateBreak",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(model),
success: function (data) {
...
并将 [FromBody] 添加到动作中
public async Task<IActionResult> CreateBreak([FromBody] Break newBreak)
恕我直言,您使用 Model
结构不必要地使 Controller
方法复杂化。由于您只需要将 EmployeeId
和 EmpPosition
变量发送到 Controller
方法,您可以这样做:
//Add Break
$(document).on("click", "#break_submit", function () {
var EmployeeId = Number($("#EmpId").val());
var EmpPosition = Number($("#EmployeePosition").val());
var json = {
EmployeeId: EmployeeId,
EmpPosition: EmpPosition
};
console.log("Model", json);
$.ajax({
type: "post",
//url: "/Home/CreateBreak",
url: "@Url.Action("CreateBreak", "Home")",
dataType: "json",
data: {"json": JSON.stringify(json)},
success: function (data) {
if (data.success)
{
$(" #headerRefresh ").load(window.location.href + " #headerRefresh ");
$(" .dthRefresh ").load(window.location.href + " .dthRefresh ");
}
else
alert("Error: Please enter your name AND position");
},
error: function () {
alert("Error: Please enter your name AND position");
}
});
});
您的 Controller
方法将如下所示:
//Create//
[HttpPost]
public async Task<IActionResult> CreateBreak(string json)
{
Break newBreak=new Break();
int EmployeeId=0;
int EmpPosition=0;
if(!string.IsNullOrEmpty(json))
{
var jsonData = JsonConvert.DeserializeObject<dynamic>(json);
EmployeeId = Convert.ToInt32(jsonData.EmployeeId);
EmpPosition = Convert.ToInt32(jsonData.EmpPosition);
newBreak.EmployeeId = EmployeeId;
newBreak.EmpPosition = EmpPosition;
if (ModelState.IsValid)
{
newBreak.TimeEntered = DateTime.Now;
_context.Add(newBreak);
await _context.SaveChangesAsync();
return Json(new { success = true, });
}
else
{
return Json(new { success = false });
}
}
else
{
return Json(new { success = false });
}
}