Efficient method to work with JSON - c#

I receive this JSON response:
{
"status": "Ok",
"total": 105373,
"result": [
{
"id": 668839,
"cn": "A-12157-68812",
"pD": "09-12-2012",
"cCD": "06-05-2012",
"cT": "PERM",
"fN": "COMCAST CABLE COMMUNICATIONS, LLC",
"s": "NJ",
"cR": "Certified",
"pT": "ENGINEER 3",
"vC": 6,
"cddt": "html"
},
{
"id": 725695,
"cn": "A-12361-25668",
"pD": "05-28-2013",
"cCD": "12-26-2012",
"cT": "PERM",
"fN": "L'ONVIE INC.",
"s": "NY",
"cR": "Certified",
"pT": "Biochemist",
"vC": 6,
"cddt": "html"
},
{
"id": 0,
"cn": "A-11199-93239",
"pD": "05-31-2012",
"cCD": "07-18-2011",
"cT": "PERM",
"fN": "ROCKWELL AUTOMATION, INC.",
"s": "PR",
"cR": "Certified",
"pT": "Marketing Managers",
"vC": -1
}]
}
What is the best way to convert this into an object so that I can apply various LINQ transforms to query for some meaningful data?
What is the efficient way to do this?
Should I create classes like:
public class Status {
string Status {get; set;}
int Total {get; set;}
IEnumerable<Result> Results {get; set;}
}
public class Result {
string Id {get; set;}
..................
}
And then figure out mapping/casting?

If you are using a recent version of Visual Studio you can use Edit > Paste Special > Paste JSON as Classes. This will save you loads of time:)
You will need to create your own classes if you are doing anything more than simple operations on the data. You can rename the fields from Json to more suitable names by using data attributes.
It depends on which deserializer you use though - Json.net or a built in .net version.
Try searching for dataContract and dataMember if you use a built-in .net deserializer or jsonProperty if you use json.net

Try Json.NET. Check out this docs about LINQ queries. You can even use Json.NET to map your JSON to .NET objects automatically.

Related

.net Core & Swashbuckle/Swagger: How to provide raw json example?

I have a WebAPI controller with an operation returning a JSON schema. This JSON return value cannot be created by serializiation, so I designed the operation method as follow:
[HttpGet("{serviceName}/contract")]
[SwaggerResponse((int)HttpStatusCode.OK, Type = typeof(object))]
public IActionResult GetContract(string serviceName)
{
return Content("{ \"type\": \"object\" }", "application/json"); // for example ...
}
Now I like to have a or some documented return values for Swagger. But I'm unable to do that. There is the SwaggerRequestExample attribute, but as said before, this requires a return type which in my case is not applicable.
Basically I search for a way of something like that (just dynamic):
[SwaggerResponseExample((int)HttpStatusCode.OK, "{\"anyJson\": \"Yes, I am!\"}")]
Or of course, even better like that:
[SwaggerResponseExample((int)HttpStatusCode.OK, RawJsonFabricType="TypeName", RawJsonStaticMethod="MethodName")]
Use case: The JSON schemas I need to return in operation method are stored in a database and are not created within the program code itself.
A concrete example of such a JSON schema value is:
{
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
}
}
Help will be very appreciated.
Thanks!
I'm using c#.net core 6.
Afer trying arround I came to the solution:
First: Add ExampleProvider and use generic type JsonDocument (from System.Text.Json):
public class ServiceDemandContractExampleProvider : IExamplesProvider<JsonDocument>
{
/// <inheritdoc/>
public JsonDocument GetExamples()
{
var jsonToShow = JsonDocument.Parse(#"{
""$id"": ""https://example.com/person.schema.json"",
""$schema"": ""https://json-schema.org/draft/2020-12/schema"",
""title"": ""Person"",
""type"": ""object"",
""properties"": {
""firstName"": {
""type"": ""string"",
""description"": ""The person's first name.""
},
""lastName"": {
""type"": ""string"",
""description"": ""The person's last name.""
},
""age"": {
""description"": ""Age in years which must be equal to or greater than zero."",
""type"": ""integer"",
""minimum"": 0
}
}
}");
return jsonToShow;
}
}
To JsonDocument.Parse put whatever JSON (in my case loaded content from database).
Then add the follow attributes to the operation method:
[SwaggerResponse((int)HttpStatusCode.OK, Type = typeof(object))]
[SwaggerResponseExample((int)HttpStatusCode.OK, typeof(ServiceDemandContractExampleProvider))]
And it works:

How to bind json response data to custom class when field name is used as data type

The below snippet is the response data which i'am getting in JSON format.
Now i need to bind these data to custom class. But there is a problem, where one of my field name is 'double'.Here i can not use double as a field name since it is a C# keyword.
Please suggest how to bind the below data to custom class.
{
"guest": {
"first_name": "Abc",
"last_name": "Def",
"email": "abc#def.com",
"country_code": "+91",
"phone": "1234567890"
},
"booking": {
"single": 0,
"double": 1,
"extra": 0,
"checkin": "19/09/2017",
"checkout": "20/09/2017",
"hotel_id": "1234",
"is_provisional":"true",
"external_reference_id": "asasa"
}
}
Actually you can use double or any other keyword as a field name and other named entities. You just need to prefix it with an #. In your case public double #double

Getting error parsing a Json response from a service c#

I am consuming an api from a .NET project and I am getting a json response, but I can't parse it correctly using Newtonsoft.Json.
I want to get the values like eda50ef6a96442088e88401ffb4846df or 965507aad38245b1b7cc62a397c9af2e. I also checked this json with an online json validator and it says it's wrong. What should I do? Any help?
{
"resp": {
"state": "ok",
"Query": {
"Header": {
"Cell": {
"HeaderName": "Guid",
"Type": "System.Guid"
}
},
"Row": {
"Cell": {
"name": "Guid",
"eda50ef6a96442088e88401ffb4846df"
}
},
"Row": {
"Cell": {
"name": "Guid",
"965507aad38245b1b7cc62a397c9af2e"
}
}
}
}
}
I also put here the response of the service in xml format.
<resp state="ok">
<Query>
<Header>
<Cell>
<HeaderName>Guid</HeaderName>
<Type>System.Guid</Type>
</Cell>
</Header>
<Row>
<Cell name="Guid">eda50ef6a96442088e88401ffb4846df</Cell>
</Row>
<Row>
<Cell name="Guid">965507aad38245b1b7cc62a397c9af2e</Cell>
</Row>
</Query>
</resp>
As others have already pointed out, the "JSON" being produced by this API is definitely invalid as it does not conform to the JSON standard.
I want to address the second part of your question, "What should I do?"
Obviously, if you control the project or API which is producing this JSON, then you should fix it to make it produce valid JSON. Instead of hand-coding the output (which is most likely how this output came to be) you should instead build up objects in memory (using nested dictionaries and lists would be a good choice here) and then serialize them using a proper JSON serializer like Json.Net. The serializer will be able to turn them into correct JSON for you.
If you do NOT control the sproject or API which is producing this JSON, then you should definitely notify the project author that it is producing invalid output and ask them to fix it, if possible.
If the project owner cannot be contacted, or s/he can't or won't fix it, or if you don't have time to wait for a proper fix, then you should switch to using the XML version instead. This looks to be correctly formatted and you should be able to consume this without any trouble using standard XML classes like LINQ-to-XML.
If you absolutely must have JSON to work with, for whatever reason, then you can try using Json.Net to convert the XML response directly into JSON using JsonConvert.SerializeXNode:
string json = JsonConvert.SerializeXNode(XElement.Parse(xml), Formatting.Indented);
However, there are some potential pitfalls with this approach, notably that the conversion process can produce different JSON depending on the number of nodes in the XML. See Converting between JSON and XML for more information.
With the XML shown in your question, SerializeXNode would produce this JSON:
{
"resp": {
"#state": "ok",
"Query": {
"Header": {
"Cell": {
"HeaderName": "Guid",
"Type": "System.Guid"
}
},
"Row": [
{
"Cell": {
"#name": "Guid",
"#text": "eda50ef6a96442088e88401ffb4846df"
}
},
{
"Cell": {
"#name": "Guid",
"#text": "965507aad38245b1b7cc62a397c9af2e"
}
}
]
}
}
}
It looks like the JSON is malformed to me... particularly here:
"Row": {
"Cell": {
"name": "Guid",
"eda50ef6a96442088e88401ffb4846df"
}
Note that the string you want to get has no "Key" name. So the Cell Key has a value which is a JSON object with a name Key (whose value is "Guid"), but the long string has no key name.
It should have a key for that value, something like this:
"Row": {
"Cell": {
"name": "Guid",
"value": "eda50ef6a96442088e88401ffb4846df"
}
For the JSON to be valid, it needs to consist of key/value pairs.

Deserialize Facebook Json result in C#

I'm getting the following Json format string as a result from a Facebook graph search request :
{
"data": [
{
"name": "Event A",
"start_time": "2013-11-08T19:00:00+0200",
"end_time": "2013-11-10T00:00:00+0200",
"timezone": "Europe/Bucharest",
"id": "232252355126"
},
{
"name": "Event B",
"start_time": "2013-11-08T13:00:00+0200",
"end_time": "2013-11-09T16:00:00+0200",
"timezone": "Europe/Bucharest",
"location": "Bucharest",
"id": "414334343426"
},
{
"name": "Event C",
"start_time": "2013-10-30T18:30:00+0200",
"timezone": "Europe/Bucharest",
"location": "Bucharest",
"id": "44315995273"
}
],
"paging": {
"previous": "https://graph.facebook.com/search?limit=3&type=event&q=Bucharest&since=1383930000&__paging_token=22251255126",
"next": "https://graph.facebook.com/search?limit=3&type=event&q=Bucharest&until=1383150600&__paging_token=44115995273"
}
}
I'm encountering some errors while trying to retrieve data from this JSON. I've tried with
dynamic jsonData = await facebookClient.GetTaskAsync(string.Format("https://graph.facebook.com/search?q={0}&type=event&limit={1}&offset={2}", locationKeyword, limit, offset));
dynamic result = JsonConvert.DeserializeObject(jsonData.ToString());
Some answers direct me to use JavaScriptSerializer but I don't have the namespace for that class, as I'm using API for developing Windows 8 Apps.
I can't manage how to get the events as somehow from data object.
I tried accessing the values in the immediate windows in VS as result.data but it's not working.
I search on how to make this but most answers seem to say to create a class in which the json data will fit.
Can't I achieve this with dynamic? (something like result.data.name, result.paging.previous etc)
I have done this exact thing before, except I converted into an XML, My Example:
(1 - JavaScript) var finalStr = JSON.stringify(facebookString)
(2 - ASP.NET) JsonConvert.DeserializeXmlNode("{\"root\":" + received_json + "}","root");
I managed at last to access the members...
To access name for example, or start_time, I did the following :
dynamic jsonData = await facebookClient.GetTaskAsync(string.Format("https://graph.facebook.com/search?q={0}&type=event&limit={1}&offset={2}", locationKeyword, limit, offset));
var result = JObject.Parse(jsonData.ToString());
var array = new JArray(result["data"]);
var a = array[0];
string name = (string) a.SelectToken("name");
var date = (DateTime?) a.SelectToken("start_time");
There might be better implementations but this one worked in my case. I posted it, in case it might be of help to others seeing this post.
Best wishes.

convert json string into array or object

I get some json data form the web which is like:
[{
"pk": 1,
"model": "stock.item",
"fields": {
"style": "f/s",
"name": "shirt",
"color": "red",
"sync": 1,
"fabric_code": "0012",
"item_code": "001",
"size": "34"
}
}, {
"pk": 2,
"model": "stock.item",
"fields": {
"style": "febric",
"name": "Trouser",
"color": "red",
"sync": 1,
"fabric_code": "fabric code",
"item_code": "0123",
"size": "44"
}
}]
How can i use it in the C# winforms desktop application. I already get this data in the form of string.
Edit:
I also try to use this way..
JavaScriptSerializer ss = new JavaScriptSerializer();
object itm = ss.DeserializeObject(responseFromServer);
It returns 'System.Object[]' but i also dont know that how i can use this.
All types of answer are welcome.
I think what your after is JSON.NET
The documentation for JavaScriptSerializer specifies that for your purpose you should use Json.NET instead.
However, if you prefer to continue to use JavaScriptSerializer you need to do the following:
JavaScriptSerializer ss = new JavaScriptSerializer();
var itm = ss.DeserializeObject(responseFromServer);
The StackOverflow thread difference-between-var-and-object-in-c-sharp describes how using var implicitly types the variable, so that it's easier to work with, where-as your code uses object, which strongly types it to an object.

Categories

Resources