【发布时间】:2016-03-28 01:42:32
【问题描述】:
我正在开发一个 ASP.Net MVC5 应用程序,在该应用程序中我试图通过 AJAX 请求将 JSON 数据传递给控制器的操作方法。 JSON 数据包含许多表单值。由于我正在尝试创建一个主详细信息表单,该表单具有以一对多格式发布到数据库中的数据,因此我创建了一个这样的对象:
var salesmain = {
"SalesId": "",
"ReferenceNo": "",
"SalesDate": "",
"SalesPerson": "",
"SalesSubs": []
};
请注意,在上述数据中,SalesSubs 属性是一个以这种方式声明的数组:
var salessub = {
"SalesId": "",
"ItemName": "",
"Qty": "",
"UnitPrice":""
};
所以,现在我知道一个salesmain 可以包含许多salessub 或salessub 的数组。在我将一些值放入其中并将 AJAX 请求传递给操作方法后,它的 SalesSubs 数组为 null。我已经通过在那里放置一个断点来检查它:
在上图中salesmain.SalesSubs 是一个数组,是null,这就是我尝试将数据传递给操作的方式:
$.ajax({
url: '/Sales/Create',
data: addRequestVerificationToken(salesmain),
type: 'POST',
dataType: 'json',
traditional : true,
success: function (result) {
if (result.Success == "1") {
window.location.href = "/Sales/Index";
}
else {
alert(result.ex);
}
}
});
这就是我在 SalesSubs 数组中推送值的方式:
salesmain.SalesId = $("#SalesId").val();
salesmain.ReferenceNo = $("#ReferenceNo").val();
salesmain.SalesDate = $("#SalesDate").val();
salesmain.SalesPerson = $("#SalesPerson").val();
$('.tbl').DataTable().rows().data().each(function (value, index) {
salessub.ItemName = value[0];
salessub.Qty = value[1];
salessub.UnitPrice = value[2];
salesmain.SalesSubs.push(salessub);
});
在上面的代码中,我使用 jQuery 的数据表插件从 DataTable 中获取整个 salessub 数据。我认为salesmain在ajax请求执行之前包含了完整的有效数据,但是ajax请求执行后不知何故没有携带salesmain对象的数组数据(SalesSubs)。
我的 AJAX 部分代码有什么问题吗?使用 AJAX 请求将 JSON 数据传递给操作方法的正确方法是什么?
编辑:
这是 SalesMain.cs 模型:
public class SalesMain
{
[Key]
public int SalesId { get; set; }
public string ReferenceNo { get; set; }
public DateTime SalesDate { get; set; }
public string SalesPerson { get; set; }
public virtual ICollection<SalesSub> SalesSubs { get; set; }
}
和 SalesSub.cs 模型:
public class SalesSub
{
[Key, Column(Order = 0)]
public int SalesId { get; set; }
[Key, Column(Order = 1)]
public string ItemName { get; set; }
public int Qty { get; set; }
public decimal UnitPrice { get; set; }
public virtual SalesMain SalesMain { get; set; }
}
和 SalesController 创建方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "SalesId,ReferenceNo,SalesDate,SalesPerson")] SalesMain salesmain)
{
try
{
if (ModelState.IsValid)
{
// Perform Update
if (salesmain.SalesId > 0)
{
var CurrentsalesSUb = db.SalesSubs.Where(p => p.SalesId == salesmain.SalesId);
foreach (SalesSub ss in CurrentsalesSUb)
db.SalesSubs.Remove(ss);
foreach (SalesSub ss in salesmain.SalesSubs)
db.SalesSubs.Add(ss);
db.Entry(salesmain).State = EntityState.Modified;
}
//Perform Save
else
{
db.SalesMains.Add(salesmain);
}
db.SaveChanges();
return Json(new { Success = 1, SalesID = salesmain.SalesId, ex = "" });
}
}
catch (Exception ex)
{
return Json(new { Success = 0, ex = ex.Message.ToString() });
}
return Json(new { Success = 0, ex = new Exception("Unable to save").Message.ToString() });
}
如果我在发送 ajax 请求之前console.log(salesmain),这就是我得到的:
所以,我认为上面的数据可以通过ajax请求移动,但是现在当它到达动作时salesmain.SalesSubs变成null,并且数据库中只填充了SalesMain表,而SalesSub表保持为空(未实现映射)。
进一步编辑:
添加contentType : 'application/json' 和data : JSON.stringify(salesmain) 导致500 内部服务器错误,在控制台窗口中检查后,错误显示:
The required anti-forgery form field “__RequestVerificationToken” is not present.
它真的不存在吗?因为我已经为此创建了一个函数:
function addRequestVerificationToken(data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};
当我使用contentType : "application/json"和JSON.stringify()时,上面的代码没有将令牌添加到salesmain,当这两个被删除时它会添加。
【问题讨论】:
-
这听起来像是 ModelBinder 的问题。您能否在请求中添加您发送的确切 JSON 字符串以及接收操作的签名(以及类大纲)
-
感谢您的回复 :),我已经更新了我的问题,请看一下。
-
在 ajax 请求中添加 contentType: 'application/json, charset=utf-8'
-
@Santosh,我也试过这个,添加 contentType: 'application/json' 甚至不将数据传递给动作,在客户端出现错误
The required anti-forgery form field "__RequestVerificationToken" is not present,它没有读取令牌字段,为了论证,我删除了 [ValidateAntiForgery] 动作过滤器,然后检查它,SalesSubs仍然是null:( -
您的
Bind属性不包括SalesSubs,因此模型绑定器在解析模型时会忽略它
标签: jquery json ajax asp.net-mvc-5