C# 在.NETCore中使用Ajax发布多个模型对象
我一直在绞尽脑汁研究同一主题的各种SO帖子(请参阅,等等),但我在从Ajax调用到控制器(.NET Core)的多个对象发布时遇到了问题。我相信我已经像本教程()一样设置了我的代码,并且还使用了这里的建议:没有用 问题是:我只能绑定第一个对象,但不能绑定第二个对象 控制器方法:C# 在.NETCore中使用Ajax发布多个模型对象,c#,jquery,ajax,asp.net-core-mvc,model-binding,C#,Jquery,Ajax,Asp.net Core Mvc,Model Binding,我一直在绞尽脑汁研究同一主题的各种SO帖子(请参阅,等等),但我在从Ajax调用到控制器(.NET Core)的多个对象发布时遇到了问题。我相信我已经像本教程()一样设置了我的代码,并且还使用了这里的建议:没有用 问题是:我只能绑定第一个对象,但不能绑定第二个对象 控制器方法: [HttpPost] [ValidateAntiForgeryToken] public IActionResult Apply(ApplicationInfoViewModel info, SRAgreementVie
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Apply(ApplicationInfoViewModel info, SRAgreementViewModel agreement)
{
if(ModelState.IsValid){
//do stuff. ModelState.IsValid returns false here.
}
}
以下是我的JS:
$(function () {
$("#ApplyBAOForm").submit(function (e) {
var jsonObj = $('#ApplyForm').serialize();
var srFormJsonObj = $('#SRForm').serialize();
$.ajax({
url: "ApplyBao/Apply",
datatype: "json",
contentType: "application/json; charset=utf-8",
data: { info: jsonObj, agreement: srFormJsonObj },
type: "POST"
}).done(function (result) {
console.log("Apply success: " + result);
if (result.type === "success") {
//hooray
}
else {
//boo
}
});
});
});
所以这是一个有点奇怪的情况:这里实际上有来自两种不同形式的数据。SRform数据在提交ApplyForm之前进行验证(它处于模式中),但实际上仅提交以与ApplyForm一起持久化。从这两种形式得到的序列化对象似乎是正确的和相似的(jsonObj和srFormObj)
当我点击ModelState.IsValid语句时,它返回false,因为SRAgreement对象本质上是null(使用默认值)。但是,ApplicationInfoViewModel对象正确显示表单中的数据
我尝试过的其他事情:
- 将两个对象合并为一个视图模型(两个子对象 结果是无效的?)
- 将SRAgreement对象添加为ApplicationInfo对象的子对象;SRAgreement对象为null李>
- 如Andrew Lock的博客文章所述,添加[FromBody],此jsut导致HTTP 415不支持的媒体类型响应
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Apply([FromBody] ApplicationInfoViewModel info)
{
if (ModelState.IsValid)
{
// do stuff
}
}
JS:
现在请求如下所示:
Request URL:http://localhost:19194/ApplyBao/Apply
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:19194
Response Headers
view parsed
HTTP/1.1 400 Bad Request
Server: Kestrel
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNccmdiMDA3M1xEb2N1bWVudHNcYmFvYWRtaW5pc3RyYXRpb25cc3JjXEJBT0FkbWluaXN0cmF0aW9uXEFwcGx5QmFvXEFwcGx5?=
X-Powered-By: ASP.NET
Date: Thu, 12 Jan 2017 21:59:27 GMT
Content-Length: 0
Request Headers
view parsed
POST /ApplyBao/Apply HTTP/1.1
Host: localhost:19194
Connection: keep-alive
Content-Length: 580
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Origin: http://localhost:19194
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: application/json; charset=UTF-8
Referer: http://localhost:19194/ApplyBao
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: .AspNetCore.Antiforgery.l7Q8WGuEtq8=CfDJ8K9L5D4kNnBPrb3_9Hu-w57rjjf751Qf9eh-z57qWmtMA53AB6FXsZ7pbIuLkdP2F6GjA7TGl0Tz7TfACCn3QeFt_uC-BgsYnk3Nd8z0ZA0c90XVEA90NnQOnmVFRu_KF2_2DXV89Jur84rMa-s26nQ
Request Payload
view parsed
{"info":{"HearAboutUsSelectedId":"137","FirstName":"Ron","LastName":"Bud","MiddleName":"","MaidenName":"","Email":"r@test.com","BirthDate":"1900-01-15","Phone":"123456","Fax":"","Street":"1234","City":"Denton","State":"TX","Zip":"12345","Country":"USA","SelectedExamTrack":"BCaBA","SelectedTranscriptSendMethod":"requested","Degree":"Education","SraId":"00000000-0000-0000-0000-000000000000","__RequestVerificationToken":"CfDJ8K9L5D4kNnBPrb3_9Hu-w56wPCITEDVZQo7flUIB70Pu4Q81TlRXa_oI4t8Bleou6l45oHHmUFrKusKofA6Gey-uSgKP7M3L-DrawE1TVJnrDsULHlnOE9ngg9LuyFK6-cylBJ-91h5fmaico-0yrZE"}}
JSON现在看起来像一个合适的JSON对象,但我的公主似乎在另一座城堡里。为了实现这一点,我还遗漏了其他一些东西吗
更新:
我终于明白了。结果证明是防伪标识导致了
请求失败,如下所述:
现在把它去掉让我可以继续前进。谢谢 您实际发送的不是2个对象,而是1个包含2个其他对象的对象。这就是这一行,创建一个将被发送的对象
data: JSON.stringify( { info: jsonObj, agreement: srFormJsonObj } ), // this is a single object that is created and sent by the http action
您需要在服务器上以相同的方式接收它,并使用一个模型,该模型包含当前用作方法参数的两种类型
模型代码
public class Model{
public ApplicationInfoViewModel Info{get;set;}
public SRAgreementViewModel Agreement {get;set;}
}
控制器代码
public IActionResult Apply([FromBody]Model model)
{
if(ModelState.IsValid){
//do stuff. ModelState.IsValid returns false here.
}
}
编辑
该错误可能是因为您正在发送url编码的数据和json以及json对象。您应该使用其中一种,但不能同时使用两者。如果查看最新更新,您可以看到为属性
info
和agreement
发送的值,它们是表单编码的字符串值。我在.NET Core 2.1中也遇到了这个问题
似乎只有一个参数可以通过[FromBody]属性传递。
必须在一个对象中汇总所有参数
示例Ajax调用:
var data = {
messageIds: selectedIds,
read: true
};
$.ajax({
url: "@Url.Action("SetMessagesReadFlag", "Message")",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(data),
cache: false,
error: function(xhr, status, error) {
//do something about the error
alert(error);
},
success: function(response) {
if (response != null) {
grid.refresh();
}
}
});
具有虚拟辅助对象类的控制器操作:
[HttpPost]
public IActionResult SetMessagesReadFlag([FromBody] Dummy data)
{
....
return Json(true);
}
public class Dummy
{
public List<Guid> MessageIds { get; set; }
public bool Read { get; set; }
}
[HttpPost]
public IActionResult SetMessagesReadFlag([FromBody]虚拟数据)
{
....
返回Json(true);
}
公共类虚拟
{
公共列表消息ID{get;set;}
公共bool Read{get;set;}
}
将两个对象包装到视图模型中,然后只接收一个包装对象。另外,由于您是.net core,您必须具有[FromBody]
。我已经尝试将[FromBody]与包装器对象一起使用,但现在得到了“加载资源失败:服务器响应状态为415(不支持的媒体类型)”。我将进一步研究这个错误。我确实尝试过(只是再试一次)。不幸的是,模型对象的两个子对象最终都为null。知道为什么吗?@RGB-你有FromBody属性吗(请参见编辑)?我也尝试过,但现在得到的是“加载资源失败:服务器响应状态为415(不支持的媒体类型)”。我仍在想该怎么办。在ajax调用中围绕您的模型放置JSON.stringify(…)
。@RGB-感兴趣的是内容类型
标题。另见
[HttpPost]
public IActionResult SetMessagesReadFlag([FromBody] Dummy data)
{
....
return Json(true);
}
public class Dummy
{
public List<Guid> MessageIds { get; set; }
public bool Read { get; set; }
}