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.
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´m trying to pass my data(json) from view through ajax to my controller but this arrive null. Thanks in advance fro any help or suggestion.
This is my model.
public class TipificacionModel
{
public int Existente { get; set; }
public string Campo { get; set; }
public int Regla { get; set; }
}
public class ListasSeleccionModel{
public List<string> DatosSeleccion { get; set; }
}
public class ListaTipificaciones
{
public string NombreCampaña { get; set; }
public List<TipificacionModel> Tipificacion { get; set; }
}
public class DatosSeleccionMultiple
{
public List<String> Columnas { get; set; }
public List<ListasSeleccionModel> ListasSeleccion { get; set; }
}
public class TipificacionGeneralCampaña
{
public ListaTipificaciones CamposCreados { get; set; }
public List<DatosSeleccionMultiple> ListasDeSeleccion { get; set; }
}
This is my ajax function.
jsonListaGeneral = [];
jsonListaGeneral.push(jsonTipificacion);
jsonListaGeneral.push(jsonListasSeleccion);
console.log(jsonListaGeneral);
$.ajax({
url: '#Url.Action("crearCampManual", "DPS")',
type: 'post',
data: JSON.stringify(jsonListaGeneral),
contentType: 'application/json; charset=utf-8;',
dataType: 'json',
success: function (response) {
alert(response)
return;
},
error: function (x) {
alert(x.responseText);
}
});
This is my controller.
[HttpPost]
public ActionResult crearCampManual(TipificacionGeneralCampaña model)
{ //Here the model value is null, why?}
When i print the json in my browser console everything is good. But something bad happends, im making something wrong.
Console Browser
Break Point Controller
One issue is that the data you are sending through your AJAX call appears to be an Array:
jsonListaGeneral = [];
But your C# model isn't an array or collection:
public ActionResult crearCampManual(TipificacionGeneralCampaña model)
If you are sending an array of TipificacionGeneralCampaña objects from your AJAX to your C# Controller, then you would want your Controller definition to look like this:
public ActionResult crearCampManual(List<TipificacionGeneralCampaña> model)
And also to reiterate what #Hackereman stated in his comment, you do not need to use the JSON.Stringify function on your data before you pass it to your Controller:
$.ajax({
url: '#Url.Action("crearCampManual", "DPS")',
type: 'post',
data: jsonListaGeneral,
contentType: 'application/json; charset=utf-8;',
dataType: 'json',
success: function (response) {
alert(response)
return;
},
error: function (x) {
alert(x.responseText);
}
});
Another issue that I noticed from your Console Browser screenshot: you seem to be adding two different objects to the same JSON array before sending to your controller:
jsonListaGeneral.push(jsonTipificacion);
jsonListaGeneral.push(jsonListasSeleccion);
When creating a collection in C#, all objects in the collect need to be of the same type, meaning that they have the same Property Names and Property Types.
With how your C# Controller is currently setup, it will accept a JSON object that is structured like this:
{
CamposCreados : {
NombreCampaña : "",
Tipificacion : [
{
Existente : 0,
Campo : "",
Regla : 0
},
{
Existente : 1,
Campo : "",
Regla : 1
}
]
}
ListasDeSeleccion : [
{
Columnas : "",
ListasSeleccion : [
{
DatosSeleccion : [
{
"",
"",
""
}
]
},
{
DatosSeleccion : [
{
"",
"",
""
}
]
}
]
}
]
}
The solution is change the declaration of the Json Object.
var jsonListaGeneral = {
"CamposCreados": jsonTipificacion,
"ListasDeSeleccion": jsonListasSeleccion
}
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...
}
}
I am currently working on a map function which requires me to display the data from the extracted JSON Response. This is the part of the class I get from my JSON response. I wish to extract 'text' from the JSON Response to display in the listbox.
public class Attributes
{
public double length { get; set; }
public double time { get; set; }
public string text { get; set; } //Want to display in listbox
public long ETA { get; set; }
public string maneuverType { get; set; }
}
public class rootobject
{
public Attribute attributes { get; set; }
public string compressedGeometry { get; set; }
}
I tried learning online but the data in the example are all hard-coded. Example of what I mean hard-coded:
Any help would be greatly appreciated.
Here is the sample method in WS web service.
[WebMethod]
public rootobject GetData()
{
var rootObj = new rootobject()
{
attributes = new Attribute[2] { new Attribute() { text = "text 1" }, new Attribute() { text = "text 2" } },
compressedGeometry = "geometry 1"
};
return rootObj;
}
JavaScript code to pull data from service
var webMethod = "WS.asmx/GetData";
var parameters = "";
$.ajax({
type: "POST",
url: webMethod,
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#sel").html(msg.d);
var index = 0;
for (; index < msg.d.attributes.length; index++)
{
$("#sel").append("<option>" + msg.d.attributes[index].text + "<option>");
}
},
error: function (e) {
alert(e);
}
});
HTML for the drop down/ select
<select id="sel"></select>
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"}}]