JsonConvert deserialize only Class fields - c#

This is json:
{
"odata.metadata": ".....",
"value": [
{
"AbsEntry": 10,
"ItemNo": "....",
"UoMEntry": -1,
"Barcode": "2000000000022",
"FreeText": "Ean13"
}
]
}
This is class:
public class BarCode
{
public int AbsEntry { get; set; }
public string ItemNo { get; set; }
public string Barcode { get; set; }
public string FreeText { get; set; }
}
This method return null:
BarCode barcode = JsonParser.DeserializeObjcet<BarCode>(json);
Are there any properties or other that can cause the call DeserializeObject to deserialize me only the fields of my classes (the names are exactly those of the Json)?

You need to create class like below not BarCode
public class Value
{
public int AbsEntry { get; set; }
public string ItemNo { get; set; }
public int UoMEntry { get; set; }
public string Barcode { get; set; }
public string FreeText { get; set; }
}
or you can change the JSON format
"BarCode": [
{
"AbsEntry": 10,
"ItemNo": "....",
"UoMEntry": -1,
"Barcode": "2000000000022",
"FreeText": "Ean13"
}
]

The structure of your class should match the structure of your JSON if you want the deserialization to succeed.
If you want a partial deserialization e.g. only deserializing the values property into your class you can use this code:
JObject jObject = JObject.Parse(json);
BarCode barcode = jObject["values"].Children().First().ToObject<BarCode>();
With this solution you don't need to refactor your class or adding a new one.

You are missing the root object :
public class RootObject
{
public string __invalid_name__odata.metadata { get; set; }
public List<BarCode> value { get; set; }
}
note that the invalid name oprperty can just be remove so it will be igrored!
Even if you want only the Value part you will have to deserialise from the root, then navigate to the child properties you need.

Related

How can I convert a json string to a json array using Newtonsoft?

I am using this code to read a json file firstSession.json and display it on a label.
var assembly = typeof(ScenarioPage).GetTypeInfo().Assembly;
string jsonFileName = "firstSession.json";
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd(); //json string
var data = JsonConvert.DeserializeObject<SessionModel>(json);
foreach (SessionModel scenario in data)
{
scenarioName.Text = scenario.title;
break;
}
scenarioName.Text = data.title; // scenarioName is the name of the label
}
SessionModel.cs looks like:
public class SessionModel : IEnumerable
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
public int numberMissing { get; set; }
public string word1 { get; set; }
public string word2 { get; set; }
public string statement1 { get; set; }
public string statement2 { get; set; }
public string question { get; set; }
public string positive { get; set; } // positive answer (yes or no)
public string negative { get; set; } // negative answer (yes or no)
public string answer { get; set; } // positive or negative
public string type { get; set; }
public string format { get; set; }
public string immersion { get; set; }
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
The beginning of my json is:
{
"firstSession": [
{
"block": 1,
"name": "mark",
"title": "mark's house",
"numberMissing": 1,
"word1": "distracted",
"word2": "None",
"statement1": "string 1",
"statement2": "None",
"question": "question",
"positive": "No",
"negative": "Yes",
"answer": "Positive",
"type": "Social",
"format": "Visual",
"immersion": "picture"
},
I am getting a Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object into type "MyProject.SessionModel" because the type requires a JSON array to deserialize correctly. To fix this error either change the JSON to a JSON array or change the deserialized type so that it is a normal .NET type that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'firstSession', line 2, position 17.
How can I convert the json string to a json array? Or make one of the other modifications the debugger suggests?
you need to create a wrapper class (json2csharp.com will help you do this)
public class Root {
public List<SessionModel> firstSession { get; set; }
}
then
var data = JsonConvert.DeserializeObject<Root>(json);
data.firstSession will be a List<SessionModel>
Create a new Class and have firstSession as List of SessionModel.
public class Sessions
{
public List<SessionModel> firstSession { get; set; }
}
Remove IEnumerable from the SessionModel
public class SessionModel
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
}
Change thedeserialization part as follows
var data = JsonConvert.DeserializeObject(line);
foreach (SessionModel scenario in data.firstSession)
{
//Here you can get each sessionModel object
Console.WriteLine(scenario.answer);
}

Dynamic json property deserialize

I'm having difficulties figuring out how to deserialize a json, that has a dynamic property (for example - UserRequest::567) the property name can be any value and the UserRequest object contains other json properties that are of interest to me
I tired writing a class and I don't know what to do with that property. What are the best practices for coping with a problem like this?
{
"objects": {
"UserRequest::567": {
"code": 0,
"message": "created",
"class": "UserRequest",
"key": "567",
"fields": {
"ref": "R-000567",
"org_id": "4"
}
}
}
}
The question is what are the best practices to read through this kind of a json string?
Thank you
To Deserialize this using Newtonsoft.Json, here are the classes:
public class CreateRequest
{
public long code { get;set; }
public string message { get; set; }
[JsonProperty("class")]
public string class1 { get; set; }
public string key { get; set; }
public Fields fields { get; set; }
}
public class Fields
{
[JsonProperty("ref")]
public string refe { get; set; }
public string org_id { get; set; }
}
public class Root
{
public Dictionary<string, CreateRequest> objects { get; set; }
//The 'string' key in the dictionary is the 'UserRequest::567'
}
Then to Deserialize use:
var x = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(jsonObject).objects.Values;

How do you deserialize json into a C# object that has "#" at the beginning of the property names?

I am having trouble deserializing json I have that has an # symbol at the beginning of a lot of the property names. It is a lot of json so I don't know if just removing all # from the json is safe or if I would lose some valuable information in the values associated with properties.
I tried using a [JsonProperty("#fontName")], for example, but that didn't work (the C# object did not adopt the value I see in the JSON; it was null instead).
internal static RootObject MyMethod(string json)
{
var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
return rootObject;
}
Here is a snippet of the json I'm dealing with:
{
"document": {
"page": [
{
"#index": "0",
"row": [
{
"column": [
{
"text": ""
},
{
"text": {
"#fontName": "Times New Roman",
"#fontSize": "8.0",
"#x": "133",
"#y": "14",
"#width": "71",
"#height": "8",
"#text": "FINAL STATEMENT"
}
...
Here is an example of what I want to deserialize into:
public class Column
{
[JsonProperty("#fontName")]
public string fontName { get; set; }
public object text { get; set; }
}
public class Row
{
public List<Column> column { get; set; }
public string text { get; set; }
}
public class Page
{
public string index { get; set; }
public List<Row> row { get; set; }
public string text { get; set; }
}
public class Document
{
public List<Page> page { get; set; }
}
public class RootObject
{
public Document document { get; set; }
}
From what I see you miss one of your properties index property of your Page object.
Write it this way [JsonProperty(PropertyName ="#index")] it is better to understand. Also we don't see the definition of fontName, fontSize, x, y and so on, in separate Text class. For some reason you wrote it as just as object.
public class Text
{
[JsonProperty(PropertyName ="#fontName")]
public string FontName {get; set;}
[JsonProperty(PropertyName ="#fontSize")]
public string FontSize {get; set;}
[JsonProperty(PropertyName ="#text")]
public string TextResult{get; set;}
//other objects
}
public class Column
{
public List<Text> text { get; set; }
}

How to get inner field's value of object by using JsonProperty

I have data in json like this:
{
"data": {
"name" : "Car wash"
"changed_by": {
"id": 1,
"name": "Pascal",
"type": "user"
}
}
}
The value "Car wash" I can get like this:
public class Changes
{
[JsonProperty("name")]
public string name { get; set; }
}
How I can get the value of some changed_by object field?
I need to use this in deserializing
private void GetChanges(RawData data)
{
var changes = JsonConvert.DeserializeObject<Response<IEnumerable<Model.Json.Changes>>>(data.ChangesData);
/* some code */
}
You just need to have a class that represents the changed_by object. For example:
public class Data
{
public string name { get; set; }
public ChangedBy changed_by { get; set; }
}
public class ChangedBy
{
public int id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
Create a class hierarchy representing the structure of the data in and then use Json.Net to deserialize it into an object of this class.
Check out Json.Net

How to create class for JSON web service result in windows phone 7?

how can I create class for JSON web service result? This is my JSON result which i get from google api. so, how to create class and deserialization for this JSON object.
I created class to deserialization this JSON object like this,
string mapdetail = e.Result;
var djosn = new DataContractJsonSerializer(typeof(mapResult));
var mstr = new MemoryStream(Encoding.UTF8.GetBytes(mapdetail));
mapResult reslt = (mapResult)djosn.ReadObject(mstr);
mapResult class:
[DataContract]
public class mapResult
{
[DataMember]
public string status
{
get;
set;
}
[DataMember]
public IList<Resultdetail> result
{
get;
set;
}
}
So i creadet list for result details and others:
[DataContract]
public class Resultdetail
{
[DataMember]
public List<string> types
{
get;
set;
}
[DataMember]
public string formatted_address
{
get;
set;
}
[DataMember]
public List<object> address_components
{
get;
set;
}
[DataMember]
public List<Geometry> geometry
{
get;
set;
}
}
[DataContract]
public class Geometry
{
[DataMember]
public List<GeoLocation> location
{
get;
set;
}
[DataMember]
public string location_type
{
get;
set;
}
[DataMember]
public List<object> viewport
{
get;
set;
}
[DataMember]
public List<object> bounds
{
get;
set;
}
}
[DataContract]
public class GeoLocation
{
[DataMember]
public double lat
{
get;
set;
}
[DataMember]
public double lng
{
get;
set;
}
}
Now I'm getting Null reference;
There were a few issues with your DatContract classes.
I've corrected these below, commented out the original lines and added a comment about what was specifically wrong.
[DataContract]
public class mapResult
{
[DataMember]
public string status { get; set; }
[DataMember]
//public IList<Resultdetail> result { get; set; }
// Misspelt property name and use of interface rather than concrete type
public List<Resultdetail> results { get; set; }
}
[DataContract]
public class Resultdetail
{
[DataMember]
public List<string> types { get; set; }
[DataMember]
public string formatted_address { get; set; }
[DataMember]
public List<object> address_components { get; set; }
[DataMember]
//public List<Geometry> geometry { get; set; }
// Json does not contain an array/list of these
public Geometry geometry { get; set; }
}
[DataContract]
public class Geometry
{
[DataMember]
//public List<GeoLocation> location { get; set; }
// Json does not contain an array/list of these
public GeoLocation location { get; set; }
[DataMember]
public string location_type { get; set; }
[DataMember]
// public List<object> viewport { get; set; }
// Json does not contain an array/list of these
public object viewport { get; set; }
[DataMember]
//public List<object> bounds { get; set; }
// Json does not contain an array/list of these
public object bounds { get; set; }
}
The following code shows that this works:
var jsonStr = "{\"status\": \"OK\", \"results\": [ { \"types\": [ \"route\" ], \"formatted_address\": \"7th Main Rd, Koramangala, sengaluru, Karnataka 560034, India\", \"address_components\": [ { \"long_name\": \"7th Main Rd\", \"short_name\": \"7th Main Rd\", \"types\": [ \"route\" ] }, { \"long_name\": \"Koramangala\", \"short_name\": \"Koramangala\", \"types\": [ \"sublocality\", \"political\" ] }, { \"long_name\": \"Bengaluru\", \"short_name\": \"Bengaluru\", \"types\": [ \"locality\", \"political\" ] }, { \"long_name\": \"sengaluru\", \"short_name\": \"sengaluru\", \"types\": [ \"administrative_area_level_2\", \"political\" ] }, { \"long_name\": \"Karnataka\", \"short_name\": \"Karnataka\", \"types\": [ \"administrative_area_level_1\", \"political\" ] }, { \"long_name\": \"India\", \"short_name\": \"IN\", \"types\": [ \"country\", \"political\" ] }, { \"long_name\": \"560034\", \"short_name\": \"560034\", \"types\": [ \"postal_code\" ] }],\"geometry\": { \"location\":{ \"lat\": 12.9259085, \"lng\": 77.6334715 }, \"location_type\": \"GEOMETRIC_CENTER\", \"viewport\": { \"southwest\": { \"lat\": 12.9227118, \"lng\": 77.6301852 }, \"northeast\": { \"lat\": 12.929007, \"lng\": 77.6364805}}, \"bounds\": { \"southwest\": { \"lat\": 12.9247615, \"lng\": 77.6330486 },\"northeast\": { \"lat\": 12.9269574, \"lng\": 77.6336171 }}}}]}";
// If using json.net (http://json.codeplex.com/)
var des = JsonConvert.DeserializeObject<mapResult>(jsonStr);
// If using System.Runtime.Serialization.Json
var djosn = new DataContractJsonSerializer(typeof(mapResult));
var mstr = new MemoryStream(Encoding.UTF8.GetBytes(jsonStr));
des = (mapResult)djosn.ReadObject(mstr);
var latitude = des.results[0].geometry.location.lat;
var longitude = des.results[0].geometry.location.lng;
Note that my code is tested with your sample json object only and is not guaranteed to work with everything returned by the web service. You're also deserialising quite a lot to object which may be awkward to work with if you want more than just the latitude and longitude.
I note that your top-level list is called result whereas the JSON name is results btw - could it be as simple as that? Maybe the deserializer is ignoring the results value because you don't have a property of that name.
If that doesn't work... You've got 7 dereferencing operations in that statement. (4 obvious ones and 3 array indexing operations). That's an awful lot of possible failure points. I suggest you put a break point on that statement (to break before it executes) and then use the watch window to look at what results you've actually got.
(Personally I've used Json.NET in Windows Phone 7 rather than the built-in libraries, but I'm sure the latter should work too.)

Categories