ASP.NET Core 3.1 Web API with $.ajax--加载资源失败 400 错误
ASP.NET Core 3.1 Web API with $.ajax--failed to load resource 400 error
我有一个使用按钮动态加载的 PartialView。当我单击“保存”时,表单将发布到 API Controller,Bp。我收到 400 HTTP 错误:加载资源失败。我用谷歌搜索,直到脸色发青,找不到解决方案。通常我遇到的问题是发布的 JSON 对象与 C# class 不匹配。我在另一个有效的程序中有类似的代码,但我看不出它们有何显着差异。任何帮助将不胜感激。
EditBP.cshtml
@model BP
<div style="z-index: 999998; opacity: 0.65; filter: alpha(opacity=65); left: 0px; width: 100%; cursor: default;
position: absolute; top: 0px; height: 100%; background-color: white">
</div>
<div style="border: 1px solid black; z-index: 999999; left: 5%; width: 90%; cursor: default; position: absolute;
top: 1%; background-color: white">
<div class="d-flex justify-content-between ed mb-3">
<div class="p-2" style="font-size:x-large">Add/Edit Boilerplate</div>
<div class="p-2" style="font-size:x-large"><button id="Close"><span class="glyphicon glyphicon-remove"></span></button></div>
</div>
<div class="d-sm-flex flex-sm-row">
<div class="p-2" style="width:50%">
@await Component.InvokeAsync("Boilerplate", new { user = User.Identity.Name })
</div>
<div class="p-2" style="width:50%">
<form id="formBP" name="formBP" method="post" data-bpapi="@ViewBag.BpApi">
<div class="form-group p-2 w280">
<select class="form-control" data-live-search="true" asp-for="BPCPTID" asp-items="ViewBag.StudyType" required></select>
</div>
<input asp-for="MDIDBP" type="hidden" value="@ViewBag.MD" />
<div class="font-weight-bold p-2">CPT Procedure</div>
<div><textArea asp-for="CPTProcedureBP" class="form-control" rows="10"></textArea></div>
<div class="font-weight-bold p-2">
TechDescription
<span style="margin-left:25px">
<select class="form-control2" asp-for="AgeGroup" asp-items="ViewBag.Age"></select>
</span>
</div>
<div><textArea asp-for="TechDescriptionBP" class="w600 form-control" rows="10"></textArea></div>
<div class="font-weight-bold p-2">
Impression
<span class="form-check-inline" style="margin-left:25px">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" asp-for="Abnormal"><span style="vertical-align:baseline;font-weight:normal"> Abnormal</span>
</label>
</span>
</div>
<div><textArea asp-for="ImpressionBP" class="w600 form-control" rows="10"></textArea></div>
<div>
<button id="btnSave" type="button" class="btn btn-outline-dark btn-lg">Save</button>
<button id="btnClr" type="button" class="btn btn-outline-dark btn-lg">Clear</button>
<span id="bpMsg" class="text-danger" style="font-size:large"></span>
</div>
</form>
<input id="BPState" type="hidden" />
</div>
</div>
</div>
Bp控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CNPLog.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace CNPLog.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class BpController : ControllerBase
{
private IEEGRepository repository;
public BpController(IEEGRepository repo)
{
repository = repo;
}
[HttpPost]
public IActionResult Post(BP bp)
{
int result = repository.SaveBP(bp);
string msg = string.Empty;
if (result > 0)
msg = "Boilerplate saved.";
else
msg = "There was a problem saving boilerplate";
return Ok(new { msg = msg });
}
}
}
带有 ajax 代码
的脚本文件片段
var bpcptid = $('#BPCPTID').val();
var mdidbp = $('#MDIDBP').val();
var cptprocbp = $('#CPTProcedureBP').val();
var agegroup = $('#AgeGroup').val();
var techdesc = $('#TechDescriptionBP').val();
var abnormal = $('#Abnormal').val();
var imp = $('#Impression').val();
var bp = { BPCPTID: bpcptid, MDIDBP: mdidbp, CPTProcedureBP: cptprocbp, AgeGroup: agegroup, TechDescriptionBP: techdesc, Abnormal: abnormal, ImpressionBP: imp };
$.ajax({
url: urlBpApi,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(bp),
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function(data) {
$("#editBP").load(urlEditBP);
$('#BPState').val(getBpSerialized());
},
error: function (xhr, status, errorMsg) {
$('#bpMsg').html(errorMsg);
}
});
这是BPclass
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace CNPLog.Models
{
public enum Age : byte { DNA, Neonate, Infant, Child, Adult }
public class BP
{
[Range(1, 256, ErrorMessage = "Please select a study type")]
public int BPCPTID { get; set; }
public string CPTDescription { get; set; }
public int MDIDBP { get; set; }
public Age AgeGroup { get; set; } = Age.DNA;
public string StrAgeGroup => AgeGroup switch
{
Age.DNA => "N/A",
Age.Neonate => "Neonate",
Age.Infant => "Infant",
Age.Child => "Child",
Age.Adult => "Adult",
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(AgeGroup)),
};
public byte ByAge => AgeGroup switch
{
Age.DNA => (byte)Age.DNA,
Age.Infant => (byte)Age.Infant,
Age.Child => (byte)Age.Child,
Age.Adult => (byte)Age.Adult,
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(AgeGroup)),
};
public bool Abnormal { get; set; } = false;
public string StrAbnormal
{
get
{
return Abnormal == true ? "Abnormal" : "Normal";
}
}
public string For { get; set; }
public string CPTProcedureBP { get; set; }
public string TechDescriptionBP { get; set; }
public string ImpressionBP { get; set; }
public string Msg { get; set; }
}
}
为400错误,那是因为Ajax中的数据类型不能正确匹配模型属性。可以通过更改数据中的类型来解决。
var bp = { BPCPTID: parseInt(bpcptid), MDIDBP: parseInt(mdidbp), CPTProcedureBP: cptprocbp, StrAgeGroup: agegroup, TechDescriptionBP: techdesc, Abnormal: Boolean(abnormal) , ImpressionBP: imp };
结果:
上面的代码可以解决issue.But你的js代码还需要修改:
1.The checkbox的值一直为真,需要判断是否被选中,然后得到值:
var abnormal = $('#Abnormal').prop("checked") ? 1 : 0;
2.There 似乎没有 ID 为 Impression
的元素,但有 ID 为 ImpressionBP
的元素,请确保它存在:
var imp = $('#Impression').val();
更新:
你也可以去掉[ApiController]
,不用改js:
[Route("api/[controller]")]
//[ApiController]
[Produces("application/json")]
public class BpController : ControllerBase
{}
我有一个使用按钮动态加载的 PartialView。当我单击“保存”时,表单将发布到 API Controller,Bp。我收到 400 HTTP 错误:加载资源失败。我用谷歌搜索,直到脸色发青,找不到解决方案。通常我遇到的问题是发布的 JSON 对象与 C# class 不匹配。我在另一个有效的程序中有类似的代码,但我看不出它们有何显着差异。任何帮助将不胜感激。
EditBP.cshtml
@model BP
<div style="z-index: 999998; opacity: 0.65; filter: alpha(opacity=65); left: 0px; width: 100%; cursor: default;
position: absolute; top: 0px; height: 100%; background-color: white">
</div>
<div style="border: 1px solid black; z-index: 999999; left: 5%; width: 90%; cursor: default; position: absolute;
top: 1%; background-color: white">
<div class="d-flex justify-content-between ed mb-3">
<div class="p-2" style="font-size:x-large">Add/Edit Boilerplate</div>
<div class="p-2" style="font-size:x-large"><button id="Close"><span class="glyphicon glyphicon-remove"></span></button></div>
</div>
<div class="d-sm-flex flex-sm-row">
<div class="p-2" style="width:50%">
@await Component.InvokeAsync("Boilerplate", new { user = User.Identity.Name })
</div>
<div class="p-2" style="width:50%">
<form id="formBP" name="formBP" method="post" data-bpapi="@ViewBag.BpApi">
<div class="form-group p-2 w280">
<select class="form-control" data-live-search="true" asp-for="BPCPTID" asp-items="ViewBag.StudyType" required></select>
</div>
<input asp-for="MDIDBP" type="hidden" value="@ViewBag.MD" />
<div class="font-weight-bold p-2">CPT Procedure</div>
<div><textArea asp-for="CPTProcedureBP" class="form-control" rows="10"></textArea></div>
<div class="font-weight-bold p-2">
TechDescription
<span style="margin-left:25px">
<select class="form-control2" asp-for="AgeGroup" asp-items="ViewBag.Age"></select>
</span>
</div>
<div><textArea asp-for="TechDescriptionBP" class="w600 form-control" rows="10"></textArea></div>
<div class="font-weight-bold p-2">
Impression
<span class="form-check-inline" style="margin-left:25px">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" asp-for="Abnormal"><span style="vertical-align:baseline;font-weight:normal"> Abnormal</span>
</label>
</span>
</div>
<div><textArea asp-for="ImpressionBP" class="w600 form-control" rows="10"></textArea></div>
<div>
<button id="btnSave" type="button" class="btn btn-outline-dark btn-lg">Save</button>
<button id="btnClr" type="button" class="btn btn-outline-dark btn-lg">Clear</button>
<span id="bpMsg" class="text-danger" style="font-size:large"></span>
</div>
</form>
<input id="BPState" type="hidden" />
</div>
</div>
</div>
Bp控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CNPLog.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace CNPLog.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class BpController : ControllerBase
{
private IEEGRepository repository;
public BpController(IEEGRepository repo)
{
repository = repo;
}
[HttpPost]
public IActionResult Post(BP bp)
{
int result = repository.SaveBP(bp);
string msg = string.Empty;
if (result > 0)
msg = "Boilerplate saved.";
else
msg = "There was a problem saving boilerplate";
return Ok(new { msg = msg });
}
}
}
带有 ajax 代码
的脚本文件片段var bpcptid = $('#BPCPTID').val();
var mdidbp = $('#MDIDBP').val();
var cptprocbp = $('#CPTProcedureBP').val();
var agegroup = $('#AgeGroup').val();
var techdesc = $('#TechDescriptionBP').val();
var abnormal = $('#Abnormal').val();
var imp = $('#Impression').val();
var bp = { BPCPTID: bpcptid, MDIDBP: mdidbp, CPTProcedureBP: cptprocbp, AgeGroup: agegroup, TechDescriptionBP: techdesc, Abnormal: abnormal, ImpressionBP: imp };
$.ajax({
url: urlBpApi,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(bp),
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function(data) {
$("#editBP").load(urlEditBP);
$('#BPState').val(getBpSerialized());
},
error: function (xhr, status, errorMsg) {
$('#bpMsg').html(errorMsg);
}
});
这是BPclass
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace CNPLog.Models
{
public enum Age : byte { DNA, Neonate, Infant, Child, Adult }
public class BP
{
[Range(1, 256, ErrorMessage = "Please select a study type")]
public int BPCPTID { get; set; }
public string CPTDescription { get; set; }
public int MDIDBP { get; set; }
public Age AgeGroup { get; set; } = Age.DNA;
public string StrAgeGroup => AgeGroup switch
{
Age.DNA => "N/A",
Age.Neonate => "Neonate",
Age.Infant => "Infant",
Age.Child => "Child",
Age.Adult => "Adult",
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(AgeGroup)),
};
public byte ByAge => AgeGroup switch
{
Age.DNA => (byte)Age.DNA,
Age.Infant => (byte)Age.Infant,
Age.Child => (byte)Age.Child,
Age.Adult => (byte)Age.Adult,
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(AgeGroup)),
};
public bool Abnormal { get; set; } = false;
public string StrAbnormal
{
get
{
return Abnormal == true ? "Abnormal" : "Normal";
}
}
public string For { get; set; }
public string CPTProcedureBP { get; set; }
public string TechDescriptionBP { get; set; }
public string ImpressionBP { get; set; }
public string Msg { get; set; }
}
}
为400错误,那是因为Ajax中的数据类型不能正确匹配模型属性。可以通过更改数据中的类型来解决。
var bp = { BPCPTID: parseInt(bpcptid), MDIDBP: parseInt(mdidbp), CPTProcedureBP: cptprocbp, StrAgeGroup: agegroup, TechDescriptionBP: techdesc, Abnormal: Boolean(abnormal) , ImpressionBP: imp };
结果:
上面的代码可以解决issue.But你的js代码还需要修改:
1.The checkbox的值一直为真,需要判断是否被选中,然后得到值:
var abnormal = $('#Abnormal').prop("checked") ? 1 : 0;
2.There 似乎没有 ID 为 Impression
的元素,但有 ID 为 ImpressionBP
的元素,请确保它存在:
var imp = $('#Impression').val();
更新:
你也可以去掉[ApiController]
,不用改js:
[Route("api/[controller]")]
//[ApiController]
[Produces("application/json")]
public class BpController : ControllerBase
{}