I'm developing an ASP.Net MVC5 application in which I'm trying to pass JSON data to the controller's action method through an AJAX request. The JSON data contains a number of form values. Since I'm trying to create a master detail form which has data to be posted in one-to-many format in the database I created an object like this:
var salesmain = {
"SalesId": "",
"ReferenceNo": "",
"SalesDate": "",
"SalesPerson": "",
"SalesSubs": []
};
Note that in the above data the SalesSubs
property is an array which is declared in this way :
var salessub = {
"SalesId": "",
"ItemName": "",
"Qty": "",
"UnitPrice":""
};
So, now I get to the point where one salesmain
can contain many salessub
or array of salessub
. After I push some values in it and pass through the AJAX request to the action method it has the SalesSubs
array as null
. I've checked it by placing a breakpoint there :
In the above image salesmain.SalesSubs
, which is an array, is null
and this is how I'm trying to pass the data to the action :
$.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);
}
}
});
This is how I'm pushing values in the SalesSubs
array :
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);
});
In the above code I've used jQuery's datatable plugin to fetch the whole salessub data from the DataTable. I think the salesmain contains a complete valid data before the ajax request is executed, but somehow the ajax request did not carry the array data (SalesSubs) of the salesmain object after it is executed.
Is there anything wrong with my AJAX part of the code? What is the correct way to pass JSON data to the action method using an AJAX request?
EDIT :
Here is SalesMain.cs model :
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; }
}
and SalesSub.cs model :
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; }
}
and SalesController Create Method :
[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() });
}
and if I console.log(salesmain)
before the ajax request is sent, this is what I get :
So, I think that the above data is fine to move through the ajax request, But now when it reaches the action salesmain.SalesSubs
becomes null
, and only the SalesMain table is populated in the database, and the SalesSub table remains empty (No mapping achieved).
Further Edit :
Adding contentType : 'application/json'
and data : JSON.stringify(salesmain)
leads to a 500 internal server error, after inspection in console window, the error says :
The required anti-forgery form field “__RequestVerificationToken” is not present.
Is it really not present?, because I've already created a function for this :
function addRequestVerificationToken(data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};
the above code does not add the token to the salesmain
when I use contentType : "application/json"
and JSON.stringify()
, it adds when these two are removed.