Parsing json in ASP.NET MVC4 controller - c#

json is passed from browser using POST method to ASP.NET MVC4 application controller in server.
It contains properites from which 3 are arrays of 0.. 20 elements (in code below all of them
have only 1 element).
How to parse this json in C# ?
I tried controller with signature
public JsonResult RegisterSales(Sale mysale)
but mysale properties are not assigned.
passed json:
{ "id":"sale1",
"sale_date":"2013-11-10 19:20:44"
"taxes":[{"id":"km20pr","name":"20%","rate":0.2}],
"products":[{"id":"prod1",
"sale_id":"sale1",
"register_id":"register1",
"quantity":"1.00000"}],
"payments":[{"id":"payment1",
"sale_id":"sale1",
"register_id":"register1",
"amount": 0
}]
}
It should parsed to C# structure something like
public class Sale
{
public string id;
public DateTime sale_date;
public Tax[] taxes;
public Product[] products;
public Payment[] payments;
}
public class Tax
{
public string id, name;
public decimal rate;
}
public class Product
{
public string id, sale_id, register_id;
public decimal quantity;
}
public class Payment
{
public string id, sale_id, register_id;
public decimal amount;
}

Use NewtonSoft JSON Deserialize, like so:
class School
{
public string student;
public object[] data;
}
School datum = JsonConvert.Deserialize<School>(jsonStr);
//Do stuff with datum...
Enjoy.

You need to post data with correct content type. In this case it's application/json. MVC chooses correct binding mode based on the content type used to send data to a server.

The best thing to do is to have the same name for the json as for your accepting variable "mysale".
Example:
"mysale": { "id":"sale1",
"sale_date":"2013-11-10 19:20:44"
"taxes":[{"id":"km20pr","name":"20%","rate":0.2}],
"products":[{"id":"prod1",
"sale_id":"sale1",
"register_id":"register1",
"quantity":"1.00000"}],
"payments":[{"id":"payment1",
"sale_id":"sale1",
"register_id":"register1",
"amount": 0
}]
}
You can do this by adding the name in the AJAX call by so:
$.ajax({
...,
...,
data: JSON.stringify({mysale:data}),
...,
...
});
Now it will accept your JSON.
The reason for this is that the JSON posted will be viewed as a post value, and just like with a normal form you can catch this value by its name.
So to answer your question: adding {get;set;} is not the best way to go.

Related

C# Receiving empty object in controller

I'm trying to get some data from the request body in a POST Controller, but the console shows empty props:
The Post Controller:
[HttpPost("{id}/features")]
public ActionResult<bool> AddFeatureAsync(Guid Id, [FromBody] AddRoleFeatureRequest request)
{
Console.WriteLine(request.Name);
Console.WriteLine(request.Description);
Console.WriteLine(request.Id);
return true;
}
The AddRoleFeatureRequest class:
public class AddRoleFeatureRequest
{
public Guid Id;
public string? Name;
public string? Description;
}
The JSON data from Postman (Using body raw as Json):
{
"name": "Feature ABC",
"description": "description",
"id": "7e12b0ad-2c82-46f0-a69e-8538efb0aa60"
}
What am I doing wrong?
I'm trying to get some data from the request body in a POST
Controller, but the console shows empty props:
Your reason for getting null data on your console or in controller is pretty obvious because you have defined your AddRoleFeatureRequest class field only which doesn't allow to set any value on it. For instance, public string? Name; is a field not property. To set value, you must implement valid setter. Thus, it can be treated as valid property and able to assign value into it.
Solution:
public class AddRoleFeatureRequest
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
}
Note: Property without getter and setter will always consider as field, it will not allow you to assign value from outside.
Output:
Note: Modifying your class defination would completely resolve your issue. No other changes required.
Your "AddRoleFeatureRequest" class has capitals and your json data does not. This could be the source of your problems.
the attribute names might be the reasons because they ar different then the json keys, retry it while considering letters cases,

Not able to post data to web api controller action using FromBody Attribute

Client Side model (Type Script File) :
export interface IRecord {
id: string
amount: string,
amountConst: string,
amountLC: string,
}
Server Side model/class : I am using newtonsoft json.
If i change the Json property value to name of property in typescript file then
that column value is not visible on UI.
public class Records
{
[Key]
public string ID { get; set; }
[Column("Amount")]
[JsonProperty("Amount")]
public string Amount { get; set; }
[Column("Amount Const $")]
[JsonProperty("Amount Const $")]
public string AmountConst { get; set; }
[Column("Amount LC")]
[JsonProperty("Amount LC")]
public string AmountLC { get; set; }
}
Web Api Contoller :
[HttpPost]
[Route("Export")]
[ActionName("Export")]
public FileResult Export([FromBody]List<Records> Record)
{
try
{
}
}
Server side I am getting the exact count of records from client side
but with null property values.
To make it work you should change either the way you send a client model or server-side bindings.
If you specify [JsonProperty] attribute, the JSON deserializer expects that the JSON property name will be exactly the same as the value of propertyName argument.
For your case the model you send should look like this
[{
"ID": "11",
"Amount": "1",
"Amount Const $": "1.0",
"Amount LC": "aaa"
}]
the interface IRecord can't be used since it couldn't be bound to a server-side model.
So, you have several options to make it work:
drop IRecord interface and send the object with the structure like shown above
change server-side model so both models' properties match
write a custom Model binder for Records type (please check this) to handle your case

trying to receive JSON as a JObject

I am trying to bring in JSON data into my method. I am using Postman to send my data.
An example of my JSON is...
{"FieldData" : {"name": "david"}, "Project" : 20, "Version" : 1}
My model is
public class IncomingFormData
{
public JObject FieldData { get; set; }
public int Project { get; set; }
public int Version { get; set; }
}
My method is
[HttpPost]
public void SaveFormData(IncomingFormData FieldData)
{
string myField = FieldData.FieldData.ToString();
}
I am getting null in FieldData.FieldData and the Project and Version are showing 0.
In my earlier version that worked, I had...
An example of my JSON is...
{FieldData : '{"name": "david"}', "Project" : 20, "Version" : 1}
[HttpPost]
public void SaveFormData(string FieldData, int Project, int Version)
{
string myField = FieldData;
}
Unfortunately for me, in this version, if the value of one of the FieldData objects has an apostrophe in it, it fails. (This is correct according to the RFC).
So, I had to rewrite it.
Now, I can't get anything coming in from Postman. The method is called but nothing coming in.
Postman has Accept application/json and content-type application/json set.
Thank you.
This is not really the way I wanted to do this, but hey, it works.
My original method was in a regular MVC controller. When I tried to send the JSON, I was getting the error Cannot create abstract class
However, creating an api controller instead, with pretty much the same signature JObject FieldData and from there, passing into my regular controller, it just works.
The code below is in the api controller.
public JsonResult Post([FromBody]JObject FieldData)
{
//string myData = FieldData.ToString();
FormsController form = new FormsController();
return form.SaveFormData(FieldData);
}
Try pass this: {"IncomingFormData":{"FieldData" : {"name": "david"}, "Project" : 20, "Version" : 1}}

send neatly formatted json data to asp.net web api instead of default [FromBody] behavior

I am trying to figure out a way to send a Json formatted data to a web api controller in a neat(more natural) way.
let me explain. Suppose I have this controller:
[HttpPost]
public class StudentController : ApiController
{
public void PostSomething([FromBody] string name, [FromBody] Student s)
{
//do something
}
}
The json data that I WANT to post is something like this (as it is correctly formatted):
{
"name" : "John",
"student" : {
"id" : "1",
"age" : "22"
}
}
But what I SHOULD send for the web api to parameter bind the objects should be like this:
{
"John",
{
"id" : "1",
"age" : "22"
}
}
The problem is that if I use my desired json format, both name and student objects will be null in the PostSomething method of the controller.
How can I send a json request with a format similar to the first example to my web api controller?
In order to consume the desired JSON structure you can change the method signature of the PostSomething and introduce a class that represents the sent data. E.g.
public class StudentTransferObject {
public string Name {get; set;}
public Student Student {get; set;}
}
With the Controller:
[HttpPost]
public class StudentController : ApiController
{
public void PostSomething([FromBody] StudentTransferObject studentInformation)
{
//do something
}
}
Read text from response body and parse the objects yourself:
[HttpPost]
public async Task<string> PostSomething()
{
string result = await Request.Content.ReadAsStringAsync();
//parse here how you want
return result;
}
Dynamic serialization with custom binding or JToken.

How to pass a value to nested model by javascript?

I have a nested model with some value I want to pass it's value to controller by ajax call, i can send data fields of main model but i can't send data of nested model which are declare in model.
/****Model Code ******/
public class xyzmodel()
{
public xyzmodel()
{
address = new Addresmodel();
}
public int Id{set; get;}
public string Name {set; get;}
}
public class Addresmodel()
{
public string Address{set; get;}
public string Number{set; get;}
}
Now i have a controller
/***** Controller Action *****/
public JsonResult SavePricingSet(xyzmodel model)
{
}
/ I am try to send value to this action method by javascript /
function Data()
{
Id: $('##Html.FieldIdFor(model => model.Id)').val(),
Name : $('##Html.FieldIdFor(model => model.Name)').val(),
/**** Above ID and Name Value i can send to controller and it's also receive ***/
Address.Number : $('##Html.FieldIdFor(model => model.Address.Number)').val(),
/*** I can Get this Address.Number Value ****/
}
my question is that how can i send this type of nested model fields value
please give hint or idea
Regards,
Ajisha
Your address field has lower case a, but you're using upper case.
#Html.FieldIdFor(model => model.address.Number)

Categories

Resources