Custom Deserialization: use JsonConverter or custom override of Deserialize method? - c#

My C# model Person has properties that don't map nicely to the JSON I am getting from a RESTful request.
C# Model:
class Person {
public string First { get; set; }
public string Last { get; set; }
}
JSON Response:
{
"customer_first_name": "foo",
"customer_last_name": "bar"
}
So when I deserialize the JSOn to a Person model/object I need to map customer_first_name to First and so on (am I correct?). Should I be using a JsonConverter to achieve this? Or custom override of Deserialize method? Or something else?

Just use the [JsonProperty] attribute.
class Person {
[JsonProperty(PropertyName = "customer_first_name")]
public string First { get; set; }
[JsonProperty(PropertyName = "customer_last_name")]
public string Last { get; set; }
}

Related

How do I deserialize json string to object based on json content?

How do I deserialize json string to object depends on json content?
I would like to do this with Newtonsoft.Json, since I am using it in the whole project and it is simple for use.
Let me explain by example:
I have json string which can have to be different property object. Content depends on the tool that generates the json files, and I cannot predict the content base on the filename or something like that.
For example, I can have json file:
{
"FileCreationDate":"29-08-2018 14:56:30",
"MessageType":2,
"Messages":[
{
"MessageSequenceNumber":1,
"ModalType":5,
"Message":{
"TransactionValue":5,
"ProductAmount":5
}
}
]
}
Or I can have something like this:
{
"FileCreationDate":"29-08-2018 14:56:30",
"MessageType":1,
"Messages":[
{
"MessageSequenceNumber":1,
"ModalType":5,
"Message":{
"TransactionBusinessDate":"29-08-2018 14:54:29",
"TransactionStatus":5,
"TicketNumber":5,
}
}
]
}
You can see that both json strings have same properties except message object in messages list.
I want to deserialize to this data structure:
public class EventFileDto
{
public string FileCreationDate { get; set; }
public MessageType MessageType { get; set; }
public IEnumerable<MessageDetailsDto> Messages { get; set; }
}
public class MessageDetailsDto
{
public int MessageSequenceNumber { get; set; }
public int ModalType { get; set; }
public EventMessageDto EventMessage { get; set; }
public TransactionMessage TransactionMessage { get; set; }
}
If json string is from the first example I want deserialize message object to EventMessage property, and TransactionMessage property should be null.
In the case of second json string, I want the opposite.
I don't want use dynamic type, since mapping to the entity would be more complicated.
How can this be done?
Thank you for your help.

parsing Json with weird attribute names [duplicate]

How can we parse if json fields contains a colon(:)? Like this:
{
"dc:creator":"Jordan, Micheal",
"element:publicationName":"Applied Ergonomics",
"element:issn":"2839749823"
}
In fact I wonder how to do this with a library like restsharp, for mapping?
Using Json.Net
string json = #"{
""dc:creator"":""Jordan, Micheal"",
""element:publicationName"":""Applied Ergonomics"",
""element:issn"":""2839749823""
}";
var pub = JsonConvert.DeserializeObject<Publication>(json);
public class Publication
{
[JsonProperty("dc:creator")]
public string creator { set; get; }
[JsonProperty("element:publicationName")]
public string publicationName { set; get; }
[JsonProperty("element:issn")]
public string issn { set; get; }
}
OR
Console.WriteLine(JObject.Parse(json)["dc:creator"]);
If you use DataContractJsonSerializer, DataMemberAttribute has property Name which can be used to override default name. This means that when you deserialize json value of property dc:creator is assigned to Publication::Creator property and on the contrary when you serialize C# object.
For example:
public class Publication
{
[DataMember(Name="dc:creator")]
public string Creator { set; get; }
[DataMember(Name="element:publicationName")]
public string PublicationName { set; get; }
[DataMember(Name="element:issn")]
public string Issn { set; get; }
}
If you choose to use Json.Net, #L.B's answer is the way to go.

JSON.Net Deserialization of non-generic Root Objects

I'm currently working on a project where I make a request to the Riot Games API, parse the JSON, and do some stuff with it. I have the request working, and I know I'm getting valid JSON. My issue is using JSON.Net to deserialize the JSON.
The JSON is of the following structure:
{
"xarcies": {
"id": 31933985,
"name": "Farces",
"profileIconId": 588,
"revisionDate": 1450249383000,
"summonerLevel": 30
}
}
I want to load this data into the following class
[JsonObject(MemberSerialization.OptIn)]
class Summoner
{
[JsonProperty("id")]
public long id {get;set;}
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("profileIconId")]
public int profileIconId { get; set; }
[JsonProperty("revisionDate")]
public long revisionDate { get; set; }
[JsonProperty("summonerLevel")]
public long summonerLevel { get; set; }
}
The issue I'm having is that because I'm given a "xarcies" object that contains the information I need, I'm not sure how to go about designing a class that can accept the JSON data. I've seen some examples that use a RootObject class to take the object and that class has a subclass that all the pairs are put into, but I can't seem to get it to work. Every time I run it the attributes for the object end up being NULL.
You can deserialize your JSON as a Dictionary<string, Summoner>:
var root = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(jsonString);
The dictionary will be keyed by the user name, in this case "xarcies". See Deserialize a Dictionary.
I just used json2csharp to create the following class (its types look a bit different then yours):
public class UserData
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public long revisionDate { get; set; }
public int summonerLevel { get; set; }
}
public class RootObject
{
public KeyValuePair<string, UserData> value { get; set; }
}

Map JSON object to c# class property

I'm getting a bunch of JSON data back from a 3rd party API like this:
returnValue = data["value"].ToObject<List<T>>();
All but one of the fields are just basic name:value pairs like this:
"Name":"Value"
I map the values I need to a class like this:
public sealed class Project
{
public string Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public DateTime ProjectDateLocal { get; set; }
public string ParentFolderName { get; set; }
public string ParentFolderId { get; set; }
//causing trouble
public Int32 ProjectTypeId { get; set; }
public string PlayerUrl
{
get
{
return "http://em.edu.edu/prj/Play/" + this.Id;
}
}
}
However, one name:value pair is complicated like this:
"CustomFieldValues":[
{
"FieldName":"ProjectTypeId","FieldDefinitionId":"37a2ffeb3bd441f6a60158458910a04d40","DataType":"Integer","Value":"100105"
}
]
I only need the FieldName(ProjectTypeId) and Value, is there a way to get just that have the class recognize that and set it in my ProjectTypeId property?
Thanks!
As #viggity stated, you can use Newtonsoft for your problem and the solution provided is good. The only thing you have to do is provide a good string json to the Deserializer.
If you want a simpler solution why don't you use data["value"].ToObject<List<Project>>() ?
Note: Assigning attributes like [JsonProperty("FieldNameFromJson")] is ussefull for mappings.
See this post for more info about how you can do this.
Use Json.net to deserialize JsonConvert.Deserialize<Project>(jsonStringContent)
Json.net will go multi levels, just add a new class and have your Project have that property.
public class CustomFieldValue
{
public string FieldName {get;set;}
public string Value {get; set;}
}
and add a list of them to your Project.
public sealed class Project
{
public string Id { get; set; }
...
public List<CustomFieldValue> CustomFieldValues { get; set; }
}
Json.net won't have any problem with it. If you don't add FieldDefinitionId, etc then Json.net will just ignore it.
http://www.newtonsoft.com/json

Json Deserialisation with subarrays doesn't contain values

I am trying to deserialise a json object. The Problem is that the the object also contains subarrays
http://i.imgur.com/WWwEVLR.png
Except for the subarrays everything is working.
I am using Newtonsoft.Json;
Here is my class
public string date_updated { get; set; }
public string date_expires { get; set; }
This is working fine.
For the subarray I did it that way:
public JsonArray contacts { get; set; }
This is my method to deserialise it:
var json = await webClient.GetAsync(new Uri(uri));
var result = await json.Content.ReadAsStringAsync();
Model = JsonConvert.DeserializeObject<Model>(result);
The Array is created well with all fields needed, but the values are not working.
The values are just: Windows.Json.JsonObject as on the picture below.
http://i.imgur.com/Q8bpCoD.png
Why is he not writing the values? How can I get them?
Thank you for your help.
The values are working fine. Using JsonArray tells the deserializer to convert the JSON data to something that is compatible with the type JsonArray. This type is simply a 1:1 representation of the JSON string underneath and is not deserialized into useful data automatically for you.
Also, JsonArray is not even part of the Json.Net library. As the debugger is telling you, it is part of the Windows.Data.Json namespace which is in a different library. You could still access the data directly from each JsonObjects using the various Get methods inside the class ( http://msdn.microsoft.com/en-us/library/windows.data.json.jsonobject.aspx ) but this is probably not the way you want to go.
In your case, you should create a class that represents the data you have inside each of those arrays. If not all entries in the array contains all of the properties of your class, don't worry. Json.Net will simply leave their value empty when deserializing. This will look like:
public class Contact
{
public string type { get; set; }
public string name { get; set; }
public string organization { get; set; }
public string full_address { get; set; }
etc.
}
For good measure, you should also respect the C# naming convention which states that properties should use CamelCase names. To help you with this, you can use the JsonProperty attribute like so:
public class Contact
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("organization")]
public string Organization { get; set; }
[JsonProperty("full_address")]
public string FullAddress { get; set; }
etc.
}
Then, you can replace the type of your contacts property to List<Contact> and the data will be automatically deserialized to a format that you can easily use.
Define new class
class Contact {
public string type { get; set; }
public string name { get; set; }
// etc
}
and modify your ReqInfo_WhoIs_Model class
public string date_updated { get; set; }
public string date_expires { get; set; }
public List<Contact> contacts { get; set; }

Categories