JSON Key name with spaces [duplicate] - c#

This question already has answers here:
RestSharp - deserialize json response with invalid key name (contains a period )
(2 answers)
Closed 1 year ago.
{
"odata.metadata": "sometext",
"odata.nextLink": "sometext",
"value": [{
"odata.type": "SP.Data.RegionsListItem",
"odata.id": "07404daa-61b5-4947-af9f-38f29822f775",
"odata.etag": "\"3\"",
"odata.editLink": "Web/Lists(guid'65dc896b-df87-4145-98d9-57c7ea619e66')/Items(3)",
"FileSystemObjectType": 0,
"Id": 3,
"ServerRedirectedEmbedUri": null,
}]
}
this is an example of my Json string i cant change its key names any sugestion? thanks in advance.

Depending on the library you are using for deserialization you can mark model fields with corresponding attributes - for example JsonPropertyNameAttribute for System.Text.Json or JsonPropertyAttribute for Newtonsoft.Json.
Newtonsoft.Json:
public class Root
{
[JsonProperty("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonProperty("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonProperty("value")]
public List<Value> Value { get; set; } // do the same for Value type
}
var result = JsonConvert.DeserializeObject<Root>(json);
System.Text.Json:
public class Root
{
[JsonPropertyName("odata.metadata")]
public string OdataMetadata { get; set; }
[JsonPropertyName("odata.nextLink")]
public string OdataNextLink { get; set; }
[JsonPropertyName("value")]
public List<Value> Value { get; set; }
}
var result = JsonSerializer.Deserialize<Root>(json);

When you create a class for your data, you can use annotations for the class members. For instance when using Newtonsoft.Json it works this way:
class MyData {
[JsonProperty("odata.metadata")]
public string Metadata {get;set;}
[JsonProperty("odata.nextlink")]
public string NextLink {get;set;}
...
}
With other libraries, the annotations may be named differently. Also make sure, you are importing the correct namespace and use the correct annotations for the library you are using. Ie for instance the System.Text.Json.JsonPropertyName annotation won't have any effect, when deserializing with Newtonsoft.Json and vice versa.
Then you can deserialize
var data = JsonConvert.DeserializeObject<MyData>(thejsonstring);
and access the property with its .NET name
var metadata = data.Metadata;

Related

Dictionary serialization: System.Exception: Type <Type> is not a dictionary

I have a dictionary in my type, which I want to get as input on controller:
using Newtonsoft.Json;
namespace LM.WebApp.Models.ApiModels;
[JsonDictionary]
public class Values
{
public Dictionary<string, string> values { get; set; }
}
public class Data
{
public bool is_active { get; set; }
public IList<string> labels { get; set; }
public string name { get; set; }
public Values values { get; set; }
}
public class DictionaryImportApiModel
{
public IList<Data> data { get; set; }
}
I'm passing on input this test JSON:
{
"data":
[
{
"is_active": true,
"labels": [
"SYSTEM",
"EXTERNAL"
],
"name": "MEDICATION_REQUEST_INTENT",
"values": {
"order": "Замовлення ліків",
"plan": "План застосування"
}
}
]
}
And getting error from question title and null dictionary in inbound object. I have changed Newtonsoft.Json serializer to Microsoft.AspNetCore.Mvc.NewtonsoftJson and removed attribute [JsonDictionary] from Values class and added .AddNewtonsoftJson() just after AddControllersWithViews in Startup. Exception is gone, but dictionary in inbound object is still null. Is it necessary to use custom converters (like this)
to handle dictionary?
Change values type of Data model to Dictionary<string, string>:
public class Data
{
public bool is_active { get; set; }
public IList<string> labels { get; set; }
public string name { get; set; }
public Dictionary<string, string> values { get; set; }
}
One of the conventions supported by main .NET json serializers (both Newtonsoft.Json and System.Text.Json, maybe some others, but have not worked with them) is converting json object to and from Dictionary, so you don't need extra wrapper class Values.
P.S.
Unless you have specific naming conventions in your project - there is no need to name classes properties the same way as they are named in the source json. For Newtonsoft.Json you can either mark properties with JsonPropertyAttribute or trying to setup corresponding NamingStrategy in serializer settings (System.Text.Json has similar options).

I have json in below format, how can i Deserialize it in C# [duplicate]

This question already has answers here:
Deserialize JSON with C#
(10 answers)
Closed 1 year ago.
{
"status": "success",
"data": {
"custid1": 723,
"custid2": 670,
"custid3": 430
}
}
It doesn't have key-value pair it just contains the value of two columns. I have tried it by converting it into a data table but not getting the required result.
You can create a class like below. and then use NewtonSoft to deserialize it to the class object.
public class Data
{
public int custid1 { get; set; }
public int custid2 { get; set; }
public int custid3 { get; set; }
}
public class Example
{
public string status { get; set; }
public Data data { get; set; }
}
Code to deserialize:
string json = <yourjson>;
Example ex = JsonConvert.DeserializeObject<Example>(json);
You can see the nugget package details here.
You can deserialize it to ExpandoObject
ExpandoObject object1 = JsonConvert.DeserializeObject<ExpandoObject>(json);

Unable to de-serialize json string [duplicate]

This question already has answers here:
How to deserialize a JSON array into an object using Json.Net?
(2 answers)
How to deserialize an array of values with a fixed schema to a strongly typed data class?
(3 answers)
Closed 4 years ago.
Below is my JSON structure:
{
"status": "success",
"data": {
"MyValues": [
[
"2018-09-06T09:15:00+0530",
1030,
1038.75,
1017.2,
1030.9,
542542
],
[
"2018-09-07T09:15:00+0530",
1032.7,
1035.45,
1015.5,
1025.35,
410461
]
]
}
}
I am using Newtonsoft JSON. To make it strongly typed, I created below classes, considering JSON structure:
class MyValues
{
public DateTime TimeStamp { get; set; }
public decimal First { get; set; }
public decimal Second { get; set; }
public decimal Third { get; set; }
public decimal Fourth { get; set; }
public decimal Fifth { get; set; }
}
class Data
{
public MyValues[] MyValues { get; set; }
}
class MyData
{
public string Status { get; set; }
public Data Data { get; set; }
}
Finally, Below is the code I have written. It reads the above json object from jd.txt file and tries to parse it:
using (StreamReader file = File.OpenText(#"jd.txt"))
{
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
MyData MyData = (MyData)serializer.Deserialize(file, typeof(MyData));
}
When I run above code, I see MyData.Data.MyValues null. I am unable to figure out the problem.
Kindly guide me to solve the problem
Your model should be:
public class Data
{
public List<List<object>> MyValues { get; set; }
}
public class MyData
{
public string status { get; set; }
public Data data { get; set; }
}
And then serialize and access to the datas:
using (StreamReader file = System.IO.File.OpenText(#"jd.txt"))
{
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
MyData MyData = (MyData)serializer.Deserialize(file, typeof(MyData));
return MyData.data.MyValues[0][0].ToString();
}
1.)Create a Mydata object and load allvariables
2.)serialize it(if it is web service output you can observe json string your in browser)
3.)according to serialized format of json you can figure out what kind of json it accepts in return.
4.)after finding json it expects you can construct that kind of json,so that it can deserialize it.
5.)For example :
Mydata object json string(which we call serialized Mydata) is like this:
{
"status":"active",
"data":{
"MyValues":[
{
"Name":"k",
"ID":"122"
},
{
"Name":"a",
"ID":"123"
}
]
}
}
then your class expects this format of json string only to convert it back to Mydata object( which we call deserialization)

How do I define an attribute for a class based on obtained JSON object?

I am able to get a JSON object with a list of surveys having a set of attributes for each of them. I have a class defined for surveys where I am defining all the survey attributes based on the obtained JSON object. I am facing an error while defining question.id attribute. Please suggest me the best way to solve this problem.
JSON Data:
"surveys":
{
"id": 20128672,
"trueFalse": false,
"question": "Any accidents on site today?",
"question.id": 1097329,
"question.tag": 0,
"images": [],
"videos": []
},
Survey class:
public class survey
{
public string id { get; set; }
public Nullable<bool> trueFalse { get; set; }
public string question { get; set; }
public string question.id { get; set; } //error in writing the question id attribute
public string desc { get; set; }
//public bool trueFalse { get; set; }
public string FormattedAnswer
{
get
{
if (trueFalse == null) return "NA";
return trueFalse == true ? "YES" : "NO";
}
}
}
I'm not sure what json lib you're using here but assuming it's json.net you can resolve this with a simple annotation mapping the json fields name to the C# property, the name you're giving that property in C# is not valid which is why you're getting the error, no periods in field names.
[JsonProperty("question.id")]
public int id { get; set; }
Also, I modified your type because it was wrong too, the json value is an int, not a string. If you're not using json.net, I'm sure you'll find similar features in the lib you are using, google json annotation or something along those lines with the packages name to find appropriate docs.

Deserialize Json C# checking if list or not [duplicate]

This question already has answers here:
How to handle both a single item and an array for the same property using JSON.net
(9 answers)
Closed 6 years ago.
Im with problem deserialize Json with newtonsoft json.
I have a class
[Serializable]
public class ValueAdd
{
[JsonProperty(PropertyName = "#id")]
public string Description { get; set; }
[JsonProperty(PropertyName = "#description")]
public string Id { get; set; }
}
[Serializable]
public class ValueAdds
{
public List<ValueAdd> ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
And the API returning the stupid two things of format: One i can serialize correct:
"ValueAdds":
{
"#size": "3",
"ValueAdd":
[
{
"#id": "2103",
"description": "some property"
},
{
"#id": "2192",
"description": "some property"
},
{
"#id": "2196",
"description": "some property"
}
]
}
But when they return one property it didnt return a list.. only return on this way:
"ValueAdds":
{
"#size": "1",
"ValueAdd":
{
"#id": "2103",
"description": "some property"
}
}
Causing me a parser error with
JsonConvert.DeserializeObject<ValueAdds>(_response);
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[myproperty]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
My question is, is there anyway to fix it?? I cant change the api response, need change from my side trying to parse if there is a list or not..
Actually, property should be either array or object. Your response should be consistent.
Anyway, to solve the problem, you should bind it to dynamic or object.
[Serializable]
public class ValueAdds
{
public dynamic ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
Then you should check the ValueAdd type.
Because in your ValueAds ValueAdd is list but in your second json its a single entity so you can not assign it, you need to create another model
[Serializable]
public class ValueAdds2
{
public ValueAdd ValueAdd { get; set; }
[JsonProperty(PropertyName = "#size")]
public string Size { get; set; }
}
then
JsonConvert.DeserializeObject<ValueAdds2>(_response);

Categories

Resources