I have to send an object from view page to controller.
Ajax code:--
var jsdata = '{p:' + data + '}';
$.ajax({
type: "POST",
url: rootURL + "Deal/Check",
contentType: 'application/json; charset=utf-8',
data:JSON.stringify(jsdata, null, 2) ,
success: function (data) {}
});
Controller:-
[HttpPost]
public async Task<ActionResult> Check(DealCreateViewModel p)
{
CheckAvailabilities(p);
return View();
}
DealCreateViewModel :--
public List<AllocationID> Titles { get; set; }
public List<AllocationID> Episodes { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Assets { get; set; }
[UIHint("MultiPicker")] public List<QuickID> Documents { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Languages { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Territories { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Countries { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Rights { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Contributors { get; set; }
[UIHint("MultiPicker")] public List<AllocationID> Transmissions { get; set; }
The object "data" which I am sending through ajax can be anything means it can be either list of assets,list of titles,list of episodes or anything else from Viewmodel.
try below code
$.ajax({
type: "POST",
url: rootURL + "Deal/Check",
contentType: 'application/json; charset=utf-8',
dataType:'json',
data: { p : data },
success: function (data) {}
});
You can send it as a simple json string. However, you won't know the type of object or the class of object. So we must specify the type along with the json string we pass to the action method. In your case, you need to specify a list type (AllocationID, QuickID), and an object class (Document, Location, etc).
Hence sample json would look like:
var jsdata = {
"listType": "AllocationID",
"objectName" : "Documents",
"data": [
//list of json object representing a document.
]
};
var dto = { jsonData: jsData };
$.ajax({
type: "POST",
url: rootURL + "Deal/Check",
data:JSON.stringify(dto),
success: function (data) {}
});
Your action method will look like:
[HttpPost]
public async Task<ActionResult> Check(string jsonData)
{
//use newtonsoft json parser
JObject obj = JObject.Parse(jsonData);
var listType = obj["listType"].Value<string>();
if(listType == 'AllocationID')
{
var jarr = obj["data"].Value<JArray>();
List<AllocationID> documents = jarr.ToObject<List<AllocationID>>();
//do something with documents list...
}
}
Related
## AJAX CALL in cshtml page ##
function ValidateData() {
var editedRows = [];
$("#eventsTable tbody tr").each(function () {
editedRows.push({
PK_WS_Event: $(this).find("td:eq(1)")[0].innerText,
Act_Id: $(this).find("td:eq(2)")[0].innerText,
WeeklyStatus: $(this).find("td:eq(3) option:selected").text()
== "--Select--" ? "" : $(this).find("td:eq(3)
option:selected").text(),
WeeklyStatusSubType: $(this).find("td:eq(4)
option:selected").text() == "--Select--" ? "" : $(this).
find("td:eq(4) option:selected").text(),
AccountName: $(this).find("td:eq(5)")[0].innerText,
AccountNumber: $(this).find("td:eq(6)")[0].innerText,
WeeklyStatusDesc: $(this).find("td:eq(7)")
[0].textContent.trim(),
});
});
$.ajax({
type: 'post',
url: "/WeeklyStatus/IndexSubmit",
data: JSON.stringify({ editedRows: editedRows }),
contentType: 'application/json',
dataType: "html",
success: function (response) {
},
error: function (xhr, status, error) {
alert('fail');
}
});
}
## Server Code Controller and ##
----------
[HttpPost]
public IActionResult IndexSubmit(IList<WeeklyStatusEvents>
editedRows)
{
return null;
}
My ViewModel as like as below..
public class ReportViewModel
{
public int SelectedStatusId { get; set; }
public int SelectedSubTypeId { get; set; }
public List<WeeklyStatusEvents> statusEvents { get; set; }
}
And WeeklyStatusEvents model as shown below
public class WeeklyStatusEvents
{
public string PK_WS_Event { get; set; }
public string Act_Id { get; set; }
//public bool INDExcludeFromRpt { get; set; }
public string WeeklyStatus { get; set; }
public string WeeklyStatusSubType { get; set; }
public string AccountName { get; set; }
public string AccountNumber { get; set; }
public string WeeklyStatusDesc { get; set; }
}
So Here, I am getting count as 0......
I have created class with all these properties. and Same property name I was used in ajax call as well.
Even I am not getting data. Can you provide the solution what i missed to get the data.
Replace
data: JSON.stringify({ editedRows: editedRows }),
with
data: JSON.stringify(editedRows),
The difference is that you want to send an array of objects instead of an object which contains an array.
In order to see the diferences between those two, I recommend you to inspect what the following lines return:
console.log(JSON.stringify(editedRows)
console.log(JSON.stringify({ editedRows: editedRows })
And add [FromBody] in front of your parameter in your action.
Add [FromBody] in front of your List and try again
[HttpPost]
public ActionResult IndexSubmit([FromBody] List<WeeklyStatusEvents> obj)
{
Vreturn null;
}
I can't figure out why my action param is coming through null. I'm also not sure of how to even diagnose the issue. I can see the http request data being sent with data and stepping through the debugger shows the object as null, not sure how to see the steps in between.
Models
public class ComplexObj
{
public int Id { get; set; }
public int Test1 { get; set; }
public decimal Test2 { get; set; }
}
public class BiggerObj
{
public BiggerObj()
{
ComplexObj = new List<ComplexObj>();
}
public long OtherId { get; set; }
public string Name { get; set; }
public ICollection<ComplexObj> ComplexObjs { get; set; }
}
Action
[HttpPost]
public void TestAction(BiggerObj[] biggerObjs)
{
...// biggerObjs is null :(
}
View
function ajaxCall() {
var data = [];
var bigObj = new Object();
bigObj.OtherId = 123;
bigObj.Name = "TestName";
bigObj.ComplexObj = [];
var complexObj = new Object();
complexObj.Id = 789;
complexObj.Test1 = 123;
complexObj.Test2 = 456;
bigObj.ComplexObj.push(complexObj);
data.push(bigObj);
}
}
$.ajax({
url: SITEROOT + "myController/TestAction",
cache: false,
type: 'POST',
data: data,
complete: function() {
alert('done');
}
});
}
Solved
You must use:
JSON.stringify and declare the contentType as "application/json; charset=utf-8"
Parse the decimal value by using parseFloat() function, decimal is considered as int by default binder.
Change your Action to this:
[HttpPost]
public ActionResult TestAction(BiggerObj[] biggerObjs)
{
...// biggerObjs is null :(
}
Change your ajaxCall function to this:
//ajaxCall
function ajaxCall() {
var data = [];
var bigObj = {
OtherId : 123,
Name : "TestName",
ComplexObjs : new Array()
};
var ComplexObjs = {
Id: 789,
Test1: 123,
Test2: parseFloat(456)
// decimal types are considered an integer, you have to parse
};
bigObj.ComplexObjs.push(ComplexObjs);
data.push(bigObj);
$.ajax({
url:"/Test/TestAction",
cache: false,
type: 'POST',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
complete: function () {
alert('done');
}
});
}
I tested, works fine.
How do I receive JSON data on my WebAPI backend in C#?
I have the following JSON sent from my JavaScript frontend.
{
"User_Id": 1,
"TotalPrice": 35,
"DeliveryAddress": "At my house",
"CartItems": [
{
"Id": 1009,
"Name": "Superman juni 2014",
"Quantity": 1,
"Price": 35
}
]
}
I have this classes:
public class PurchaseOrder
{
public List<CartItem> CartItems { get; set; }
public string DeliveryAddress { get; set; }
public int TotalPrice { get; set; }
public int User_Id { get; set; }
}
public class CartItem
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
}
And my WebAPI method:
[System.Web.Mvc.HttpPost]
public bool AddOrder(PurchaseOrder order)
{
// Here I will do something
return true;
}
I only get "null" as the result for my "PurchaseOrder order" object. Can the problem be that I´m using [System.Web.Mvc.HttpPost]? I have also tried [System.Web.Http.HttpPost], but get the same result.
// Martin
The Content-Type of your request should be "application/json"
If you post your json in a body of the request than change a method signature to
[HttpPost]
public bool AddOrder([FromBody] PurchaseOrder order)
{
}
Problem solved, it was the "application/json" that was missing. For other persons having the same problem, here is my function. I´m using Knockout.js, hence the "self"-word.
self.makePurchase = function () {
var tempUserId = self.orderUserId();
var tempCartPrice = self.ShoppingCartPrice();
var tempAddress = self.orderAddress();
var tempCart = self.ShoppingCart();
var orderSave = new PurchaseSave(tempUserId, tempCartPrice, tempAddress, tempCart);
var myData = ko.toJSON(orderSave);
console.log(myData);
$.ajax({
type: "POST",
async: false,
url: '/Products/AddOrder',
contentType: "application/json", // Thank you Stackoverflow!!!
dataType: "json",
traditional: true,
data: myData,
error: function (xhr, textStatus, errorThrown) {
console.log(xhr.responseText);
console.log("Inside the error method");
},
success: function (data) {
console.log("Inside the success method");
}
});
}
Change your implementation to this.
[System.Web.Http.HttpPost]
public bool AddOrder([FromBody] PurchaseOrder order)
{
}
For more details - http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
Try using Newtonsoft.Json package from NuGet. They have functions to serialize and deserialize any string to Json.
Also try using dynamic type variables. Helps for deserializing.
function myItemsViewModel(ItemID, GroupID, ItemName, Quantity) {
this.ItemID = ItemID;
this.GroupID = GroupID;
this.ItemName = ItemName;
this.Quantity = Quantity;
}
And i have below code for posting to the controller
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
var obj = new myRecordEntryViewModel("", Name, Department, ItemsList);
var viewmodel = JSON.stringify(obj);
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: viewmodel,
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
}
});
}
At the line var viewmodel = JSON.stringify(obj);, viewmodel has all the values that i want in my ItemsList array variable.
Problem is my ItemsList array is coming as null in the controller. Name and Department are coming through with the correct passed values.
Below is my controller code.
Class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string[] ItemsList { get; set; }
}
Save action
[ActionName("Save")]
[NoCache]
public ActionResult Save(myRecordEntryViewModel viewModel)
{
//here viewModel.ItemsList is null, what could i be missing
if (this.SaveEntry(viewModel.Name,viewModel.Department,viewModel.ItemsList))
{
}
return this.View();
}
I'm wondering why viewModel.ItemsList is coming as null in controller yet it has values during the post from jQuery.
You should create a class for the Item in Item List (In C#)
public class Item {
public string ItemName { get; set; }
public int Quantity { get; set; }
}
And then change the viewmodel class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
//public string[] ItemsList { get; set; }
public List<Item> ItemsList {get ; set;}
}
The controller can not map the Item List from your request into model because one is a list of string and other is a list of object.
There are several problems in your codes...
1) ItemList in your class and your javascript code are not same - The frist one is an array of strings, and the second is an array of objects
2) In your action method, you should change parameter type like the following:
public ActionResult Save(string viewModel)
3) In the body of your action method, you should deserialize the json string (viewModel) and make the model object from it. The following is an example...
https://stackoverflow.com/a/17741421/1814343
Try the below code and see if your model gets the values.
Let me know if you face any problems, because I've already implemented this in one of my projects
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var model="";
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
model = ['Name' : Name , 'Department' : Department , 'ItemsList' :ItemsList];
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: JSON.stringify(model),
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
HideLoader();
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
HideLoader();
}
});
}
This is my model
Model
public class XPersonContent
{
public string PersonType { get; set; }
public int PersonId { get; set; }
}
public class XViewModel
{
public List<XPersonContent> XPersonList { get; set; }
public string XContent { get; set; }
public sbyte CommentEnabled { get; set; }
}
Controller
[HttpPost]
public JsonResult AddXViewModel ( XViewModel testModel)
{
}
Form using MVC that submits to controller
function submitForm() {
var xpersonContent=[Object { Id=2934109, Type="us"}, Object { Id=2913974, Type="us"}, Object {Id=2912159, Type="us"}]
var xContent= "test";
var CommentEnabled= false;
var dataString = {
XPersonList:xpersonContent,
XContent: xContent,
CommentEnabled: true
};
$.ajax({
type: "POST",
url: "/AjaxPostDemo/AddXViewModel",
data: JSON.stringify(dataString ),
cache: false,
dataType: "json",
success: function (data) {
$("#ajaxPostMessage").empty();
$("#ajaxPostMessage").html(data.Message + " : " + data.Date);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
}
> Question
How do i build the object XViewModel to pass back to the controller. i have them in three different variables
i have tried to do this
dataString = {
XPersonList:xpersonContent,
XContent: xContent,
CommentEnabled: true
};
but its not working..
I had to add
contentType: "application/json; charset=utf-8",
in my ajax request
SMH
Try change to this
var xpersonContent=[{"XPersonContent": {"Id": 2934109, "Type": "us"}}, {"XPersonContent": {"Id": 2913974, "Type": "us"}}, {"XPersonContent": {"Id": 2912159, "Type": "us"}}]