This question already has an answer here:
Deserializing JSON into an object
(1 answer)
Closed 5 years ago.
I have the following string of Json records:
{
"records":[
{
"PK":"1_1_8",
"ID":"8",
"DeviceID":"1",
"RootID":"1",
"CustName":"test1",
"CustSurname":"test2",
"Address":"Nisou 1",
"City":"",
"ZipCode":"",
"PhoneNumber":"45646",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":"1",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 10:15:00",
"modified":"2017-10-25 09:35:43"
},
{
"PK":"1_1_33",
"ID":"33",
"DeviceID":"1",
"RootID":"1",
"CustName":"",
"CustSurname":"",
"Address":"",
"City":"",
"ZipCode":"",
"PhoneNumber":"",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":null,
"LanguageID":"0",
"LanguagePK":"",
"DeletedFlag":"true",
"created":"2017-10-25 10:13:54",
"modified":"2017-10-25 10:13:54"
},
{
"PK":"1_1_16",
"ID":"16",
"DeviceID":"1",
"RootID":"1",
"CustName":"Theodosis",
"CustSurname":"",
"Address":"Dali",
"City":"Nicosia",
"ZipCode":"2540",
"PhoneNumber":"45645",
"HomePhoneNumber":"99123456",
"Email":"theodosis#gmail.com",
"Notes":"",
"Owner":"",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 09:36:22",
"modified":"2017-10-25 09:36:22"
}
]
}
I am using Xamarin PCL in C# trying to parse this string into a list of objects.
I have a Customer class:
public class Customer
{
[PrimaryKey]
public string PK { get; set; }
public int DeviceID { get; set; }
public int ID { get; set; }
public string RootID{ get; set; }
public string CustName { get; set; }
public string CustSurname { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string PhoneNumber { get; set; }
public string HomePhoneNumber { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
public bool Owner { get; set; }
public int LanguageID { get; set; }
public string LanguagePK { get; set; }
public bool DeletedFlag { get; set; }
public DateTime created { get; set; }
public DateTime modified { get; set; }
}
I also tried out having a container class with a list of Customer objects.
public class DataContainer
{
public List<Customer> customers { get; set; }
}
I have seen quite a few of examples online on how to parse this into a list or any workable type but nothing seems to be working for me.
I have tried the following (JsonResults holds the string of Json records):
var observation = JsonConvert.DeserializeObject<DataContainer>(JsonResults);
From other posts, I am not able to access JavaScriptSerializer class from my code, perhaps because of the Xamarin PCL Framework I am using.
Any ideas would be very welcome, as I said I do not mind the format I parse the string into, as long as it's workable.
Thank you.
You would have to make the following changes to your code to make this work.
First and most importantly, you don't have a property customers, you have records, so either rename it
public class DataContainer {
public List<Customer> records { get; set; }
}
or add a JsonProperty attribute
[JsonProperty(PropertyName = "records")]
Secondly, your Owner is a bool in C# and a nullable int (int?) in Json. So either change it in your C# class
public int? Owner { get; set; }
or write a converter to do that (e.g. like here)
[JsonConverter(typeof(NullableIntToBooleanConverter))]
public bool Owner { get; set; }
Here is a working .NetFiddle
The JSON string you provided is a JSON object, which contains a single property called records. records property is a List<Customer>. You can not deserialize the given string directly into DataContainer class that you provided because the property names do not match.
In the Class that your provided it is called customers
public class DataContainer {
public List<Customer> customers { get; set; } //records
}
Or please have a look at the attribute for a bit of advanced mapping
[JsonProperty]
JSON you provided is of the form:
{"records":[{Customer},{Customer},{Customer}]}
But Owner property is "1", null or "". Therefore I would suggest redefining Owner as int? (nullable)
Your string shows one object with a property named records that contains a list of other objects. Your code is trying to deserialize this into an object that doesn't have such a property.
Furthermore, the string contains objects with a property Owner that may be missing or have a numeric value. It's definitely not a bool.
You'll have to change Owner to :
public int? Owner { get; set; }
To deserialize the string, you need an object with a records property:
public class DataContainer
{
public Customer[] records { get; set; }
}
var data=JsonConvert.DeserializeObject<DataContainer>(json);
Debug.Assert(data.records.Length == 3);
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.
I'm developing my own JSON-to-POCO framework.
The way I'm doing it is, that I created the class of a Json-schema that looks like this:
public class JsonSchema
{
public string type { get; set; }
public string title { get; set; }
public string description { get; set; }
public Dictionary<string, JsonSchema> properties { get; set; }
public JsonSchema items { get; set; }
public string id { get; set; }
public List<string> required { get; set; }
public bool ispartial = true;
}
and deserializing the schema to have my object(s) so I can work with it perfectly.
Everything is working fine for now, I'm getting my generated C#-file. But only if I don't add $refs to my json. (Since it's much less code to add a reference in json instead of copy-paste the classes I want to support them)
What I need to do is, adding the $ref to my class. Problem here is, I cannot add an attribute like
public string $ref { get; set; }
to my code.
Any idea what I could do?
The problem was also, that you cannot deserialize $id and $ref with default settings. This was solved by reading this nice post here: JsonConvert.DeserializeObject<> (string) returns null value for $id property
You may add [JsonProperty] attribute to the property you want to change the name.
[JsonProperty("$ref")]
public string reference { get; set; }
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
I receive this JSON string (part of a really big one) back from an oracle server (data is unchangeable) but now I have the tedious problem of not being able to deserialize this..
"rows":[
{
"1":"0000000001",
"2":"SPARE00002",
"5":"151.3354",
"13":"100",
"100000":"000000",
"100001":"FFFFFF",
"rowid":"0000000001"
},
with using NewtonSoft.JSon it creates the class :
public class Row
{
public string __invalid_name__1 { get; set; }
public string __invalid_name__2 { get; set; }
public string __invalid_name__5 { get; set; }
public string __invalid_name__13 { get; set; }
public string __invalid_name__100000 { get; set; }
public string __invalid_name__100001 { get; set; }
public string rowid { get; set; }
}
And while trying to deserialise into the class I get the awesome error :
Could not evaluate expression.
Is there any way to format this correctly so c# realises the string NAME is the same as the property name sent by the JSON string?
Any help is highly appreciated!
EDIT! Found the solution!
By adding [JsonProperty("1")] ..etc to the invalid name strings, the problem solved itself!
Awesome!
On each of the invalid property names, add the attribute: [JsonProperty("1")]