parsing Json with weird attribute names [duplicate] - c#

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.

Related

Convert JSON string to object C#

I have JSON string results as follows.
In this response Sometimes sizeKey and sizeName properties are returned as a string. But sometimes both properties are returns inside an array as follows
I am using following code to convert it to object
var assets = jObject["assets"].Children().ToList();
foreach (var item in assets)
{
decorationAssets.Add(item.ToObject<AEDecorationAssets>());
}
And my AEDecorationAssets class is as follows.
public class AEDecorationAssets
{
public string Id { get; set; }
public string Url { get; set; }
public string[] Colors { get; set; }
public string FontKey { get; set; }
public string SizeKey { get; set; }
public string ViewKey { get; set; }
public string FontName { get; set; }
public int Rotation { get; set; }
public string SizeName { get; set; }
public string TextValue { get; set; }
public string EntityType { get; set; }
public string LocationCode { get; set; }
public string LocationName { get; set; }
public string TextEffectKey { get; set; }
public string TextEffectName { get; set; }
public string DecorationMethod { get; set; }
public string NumDecorationColors { get; set; }
}
At the time when "sizeKey" is an array, the above code gives an error. How can I resolve this issue? Is there any JSON property we can use to resolve it?
One way you can do it is by making your SizeKey type an object (i.e. public object SizeKey { get; set; }), then you can switch/case on item.ToObject<AEDecorationAssets>().SizeKey.GetType() to figure out how to handle it (i.e. if String do this, if JArray do that), etc.
If a JSON type is sometime an array, and sometimes a string, you can't really map it simply to a .NET type, as there is none that supports this behavior.
So first you need a datatype that can store this, like and string[] or List<string>.
It could be that JsonConvert will solve this automatically, but otherwise you'll need to write a custom ContractResolver or JsonConverter. Here you can detect if the source property is a string or array. If it's an array, you can use the default deserialization. If it is a string, you need to convert it to an array with a single value.
Simply get json result for which you want to create c# object and then you can valid json response from https://jsonlint.com/ and then you can create c# object of any type json response which you want through http://json2csharp.com. And after get c# object of your json response you only need to deserialization of your json response to c# object which you have created. which will return you expected result.

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

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; }
}

Newtonsoft.Json Custom Root Name for Deserialization

I have this class that defines the json format:
public class ResultType
{
public bool status { get; set; }
public string message { get; set; }
}
The actual json looks like this:
{"result":{"status":true,"message":"Success"}}
How can I override the root attribute when de-serializing the json to "result"
JObject jsonResponse = JObject.Parse(jsonString);
ResultType _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultType>(jsonResponse["result"].ToString());
Console.WriteLine(_Data.status);
Fiddle: https://dotnetfiddle.net/gjYS2p
I have a central deserialization method, so I'm trying to avoid type specific code as much as possible.
I used the following to resolve the problem, maybe not as sexy as I was hoping for but it works.
public class ResultType
{
public ResultDetailType result { get; set; }
}
public class ResultDetailType
{
public bool status { get; set; }
public string message { 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