How to deserialize JSON with spaces in the attribute names? - c#

I have a string array that I want to deserialize. Essentially, it is just a list of objects. Note that the attributes have spaces in the names:
[ { \"Event Name\": \"Hurricane Irma PR\", \"Storm Start (LST)\": \"2017-08-30\", \"Storm End (LST)\": \"2017-09-13\", \"Grid Cell Number\": 16412, \"Grid Cell State\": \"PR\", \"Grid Cell Name\": \"Grid26_0\", ...
I created a public class to template the string based on specific attributes that I want ( I don't want all the data) but I am not sure how to handle for the spaces in the names of the attributes that I want.
public class New_Events_Dataset
{
public string EventName { get; set; }
public string StormStart { get; set; }
public string StormEnd { get; set; }
public string GridCellState { get; set; }
public string GridCellName { get; set; }
public string USGSGageSiteNo { get; set; }
public string ReturnPeriodatGridCell { get; set; }
}
When I apply the deserializer with my class New_Events_Dataset like this:
var jsonResponse = returnJson.Deserialize<List<New_Events_Dataset>>(strresult);
string json = new JavaScriptSerializer().Serialize(jsonResponse);
return json;
I end up returning something like this. What am I doing wrong?
[{"EventName":null,"StormStart":null,"StormEnd":null,"GridCellState":null,"GridCellName":null,"USGSGageSiteNo":null,"ReturnPeriodatGridCell":null}

Unfortunately keys must match exactly each other.
One of the best ways to solve your problem is to define JsonProperty attribute for each property to get Deserialized object correctly. You can specify property's json key name with it.
You can take a look to this question and it's answer for better understanding:
An example of JsonProperty
Edit:
As in comments mentioned, because you are using JavaScriptSerializer JsonPropertyAttribute doesn't work in this situation.
But you can use it by adding Newtonsoft.Json Nuget Package and using it's deserilizer this way:
JsonConvert.DeserializeObject<AzureResourceData>(jsonString);

Related

Deserialize JSON to C# Objects with Childs

I have a JSON string and I need some help to deserialize it.
At the moment my result is always null.
var results = JsonConvert.DeserializeObject<Root>(json);
// result == null
My JSON:
{"First":{"FirstData1":{"date":"2018-01-01","hint":""},
"FirstData2":{"date":"2018-01-06","hint":""}},
"Second":{"SecondData1":{"date":"2018-01-01","hint":""},
"SecondData2":{"date":"2018-01-06","hint":""}}}....
Only on the last Node there is actual property naming...
MyObjects
public class Root
{
public IEnumerable<TempModelRoot> Value{ get; set; }
}
public class TempModelRoot
{
[JsonProperty("Key")]
public string Key { get; set; }
[JsonProperty("Value")]
public List<TempModelChild> Value { get; set; }
}
public class TempModelChild
{
[JsonProperty("Key")]
public string Key { get; set; }
[JsonProperty("Value")]
public TempModelInfo Value { get; set; }
}
public class TempModelInfo
{
[JsonProperty("date")]
public string date { get; set; }
[JsonProperty("hint")]
public string hint { get; set; }
}
In addition to #MX D 's answer, I want to add two more useful model generator sites, which takes JSON as an input and gives appropriate model classes.
Json2Csahrp
JsonUtils
Use, whenever you find difficult to generate complex model classes.
Most likely you are having a mismatch between the model you are trying to deserialize to, and the actual expected model based of the json itself.
A easy way to resolve this is by using a tool such as Quick Types Model Generator(unafiliated) which allows you to generate C# models based upon a provided json file.
After generation you can compare and/or replace your models with the generated models.
To spot and resolve the issue with your model.

Modify a JSON string

I have a string in JSON format as follows
string jsonStr = "{"Type":1, "Id":1000,"Date":null,"Group": "Admin","Country":"India","Type":1}";
I want to modify this string so that Id attribute should always be the first. The order of attributes matters.
Is there any way I can modify this string.
I tried searching google but did not find appropriate solution.
Any help would be appreciated.
EDIT:
I also tried to deserialize object using
object yourOjbect = new JavaScriptSerializer().DeserializeObject(jsonStr);
But here also the "type" attribute comes first. I dont find any way to move the attributes within this deserialized object
It's possible. Use the JsonProperty attribute, property Order.
http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm.
Let me know if it works.
Instead of attempting to manipulate the order of the outputted JSON and comparing strings, I would transform both JSON strings that you want to compare, into objects and then perform your comparison. You could then compare individual properties or entire objects with something like the following:
void CompareJSON()
{
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
string jsonToCompare = "JSON TO COMPARE";
MyObject myJsonObject = JsonConvert.DeserializeObject<MyObject>(json);
MyObject myJsonObjectToCompare = JsonConvert.DeserializeObject<MyObject>(jsonToCompare);
if (myJsonObject.Id == myJsonObjectToCompare.Id)
{
// Do something
}
}
class MyObject
{
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}
Please note that this example is carried out using the Newtonsoft.JSON library. More information on the library can be found here.
Just make your JSON into a c# class with Id first and then serialize it again if that is what you need. You do know that you have "Type" twice in the JSON string? In this solution it will get "fixed" so you only have it once as it should be. But if your string really is with two Type this wont work since the strings will be incorrect. If they really are like that you need to do some ugly string manipulation to fix the order but i hope the first string is incorrect only here and not in your code.
private void Test() {
string json = #"{""Type"":1, ""Id"":1000,""Date"":null,""Group"": ""Admin"",""Country"":""India"",""Type"":1}";
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
MyJsonObject myJsonObject = jsonSerializer.Deserialize<MyJsonObject>(json);
string s = jsonSerializer.Serialize(myJsonObject);
//Returns: {"Id":1000,"Type":1,"Date":null,"Group":"Admin","Country":"India"}
}
class MyJsonObject {
public int Id { get; set; }
public int Type { get; set; }
public DateTime? Date { get; set; }
public string Group { get; set; }
public string Country { get; set; }
}

Custom mapping with Json.NET

I'm trying to map JSON that looks like
"ids": {
"id": {
"#value":"6763754764235874140"
}
}
And I'd like to map it onto a couple of classes that look like
class Property
{
public Ids Ids { get; set; }
}
class Ids
{
public string Id { get; set; }
}
So basically I want to stuff the value of ids/id/#value from the JSON document into Ids.Id in the class architecture. From browsing the documentation, I thought I could use something like
[JsonProperty(ItemConverterType=typeof(IdConverter))]
public string Id { get; set; }
and provide a custom JsonConverter subclass named IdConverter. When I do, though, my IdConverter.ReadJson never gets called. What am I doing wrong?
Looks like the answer was that ItemConverterType is for converting items in an array. Double-annotating the property with JsonProperty and JsonConverter attributes works:
[JsonProperty(PropertyName="id")]
[JsonConverter(typeof(IdConverter))]
public string Id { get; set; }

How do I remap names to object properties when deserializing, using Json.Net in C#

Case:
I receive a JSON string from third-party server, containing a list of objects.
e.g.
[{"foo": "bar", "someotherfield": "somevalue"}, {etc}, {etc}]
I have a C# class like,
public class MyObject
{
public string A { get; set; }
public string B { get; set; }
}
Now, I want to use JsonConvert.DeserializeObject, but so that it maps "foo" to A and so forth. How would I go about doing this?
You can use the JsonProperty attribute.
[JsonProperty("foo")]
public string A { get; set; }
You can use the JsonPropertyAttribute decorated on the property, giving it the name of the parameter it should find in the JSON message. You can also use a custom JsonConverter, if you do not wish to use an attribute.

How to map JSON to C# Objects

I am having issues with understanding how to make this happen.
Basically we have an API, the user sends a JSON of the format:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
I have a class called Profile with parameters Name, Last, and an object as one of its members called Client as well as property Date.
Something like this:
public class Profile {
public string Name {get; set;}
public string Last {get; set;}
public Client client {get; set;}
public DateTime dDate {get; set;}
}
So basically, I am not sure how to grab the JSON and then map it to my object.
Any help with "helping" me understand would be much appreciated.
You can use Json.NET to deserialize your json string as (with some modifications to your classes)
var yourObject = JsonConvert.DeserializeObject<Root>(jsonstring);
public class Root
{
public Profile[] Profile;
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public DateTime Date { get; set; }
}
public class Client
{
public int ClientId;
public string Product;
public string Message;
}
You can use a JSON library for this, for example Newtonsoft.Json which is free. It will map json to your types automatically.
Sample:
public static T Deserialize<T>(string json)
{
Newtonsoft.Json.JsonSerializer s = new JsonSerializer();
return s.Deserialize<T>(new JsonTextReader(new StringReader(json)));
}
There is also a NuGet package available.
Easiest way I know is to use JSON.Net by newtonsoft.
To make it easier to understand, I always make matching classes in C# with the same name.
Then its easier to deserialize it.
As an example, if it is an array of objects in js, it will map to a list of object with the same names in C#.
As for the date time, its a bit tricky.
Id do the client side validation and Datetime.tryParse in the serverside, itll take care of the dashes or slashes.
var serializer = new JavaScriptSerializer();
List<abc> abcList = serializer.Deserialize<List<abc>>(PassedInJsonString);
I know this is a long time question, but I would like to add one more option, which does not use third party libraries, and only uses stock .Net libraries, and is available from .Net Core 3.1 onwards.
First of all, I leave a link to the official Microsoft documentation (where you will find examples on how to serialize and deserialize json strings): https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to
Let's build on your example. We have our starting json string:
{
"Profile":[
{
"Name":"Joe",
"Last":"Doe",
"Client":{
"ClientId":"1",
"Product":"Apple",
"Message":"Peter likes apples"
},
"Date":"2012-02-14"
}
]
}
If we build a data structure that can hold that definition, it would be something like:
public class Root
{
public List<Profile> Profile { get; set; }
}
public class Profile
{
public string Name { get; set; }
public string Last { get; set; }
public Client Client { get; set; }
public string Date { get; set; }
}
public class Client
{
public string ClientId { get; set; }
public string Product { get; set; }
public string Message { get; set; }
}
Now, and finally the answer to how to deserialize a json string into a particular object without third party libraries:
Root root = JsonSerializer.Deserialize<Root>(json);
Where json is the variable that contains your json string.
I add another link of interest, the official documentation of the Deserialize(...) method: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.deserialize
Something that is really useful is the exception that can be thrown, JsonException: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonexception
DataContractJsonSerializer does the job, but it uses more sophisticated format for DateTime serialization.

Categories

Resources