Trouble deserializing JSON (got value array when single value expected) - c#

I am reading data from a graph database and getting the response as a dynamic object. I go through the results and try to deserialize them as so:
var e = results.GetEnumerator();
while (e.MoveNext())
{
var serialized = JsonConvert.SerializeObject(e.Current);
// {"FlagCalculateclientside":[false],"Description":["Some detailed info"], "Name": ["MyDetailedEntity"]}
var val = JsonConvert.DeserializeObject<MyObject>(serialized);
}
public class MyObject
{
public bool FlagCalculateclientside { get; set; }
public string Description { get; set; }
public string Name { get; set; }
}
But I get the following error:
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: [. Path 'FlagCalculateclientside', line 1, position 28.
at Newtonsoft.Json.JsonTextReader.ReadAsBoolean()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
...
I guess this is because the values are in arrays, but only a single value per key was expected.
Any idea how to fix this?

Your model doesn't match your JSON, all of the properties are arrays, in other words they are surround with [...]. To fix, change the model to this:
public class MyObject
{
public List<bool> FlagCalculateclientside { get; set; }
public List<string> Description { get; set; }
public List<string> Name { get; set; }
}
An alternative would be to use a custom converter, for example:
public class ArrayConverter<T> : JsonConverter<T>
{
public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
//This isn't the best code but shows you what you need to do.
return token.ToObject<List<T>>().First();
}
public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And change your model to this:
public class MyObject
{
[JsonConverter(typeof(ArrayConverter<bool>))]
public bool FlagCalculateclientside { get; set; }
[JsonConverter(typeof(ArrayConverter<string>))]
public string Description { get; set; }
[JsonConverter(typeof(ArrayConverter<string>))]
public string Name { get; set; }
}

Related

Deserializing a JSON array with awkward additional property in the schema

I have a very similar issue to this question here, except my application is in C#, and I can't figure out how to convert the solution unfortunately. I am trying to deserialize a JSON result that looks like this:
"error":[],
"result":
{
"MANAEUR":[
[1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
[1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77],
],
"last":1619118000
}
I use the following classes:
public class ResponseBase
{
[JsonProperty(PropertyName = "error")]
public List<string> Error;
}
public class OHLCResponse : ResponseBase
{
[JsonProperty("result")]
public OHLCResult Result;
}
public class OHLCResult
{
[JsonProperty("pair_names")]
public Dictionary<string, OHLC[]> GetHistory;
[JsonProperty("last")]
public long Last;
}
.... and then finally the guts of it:
public class OHLC
{
public int Time;
public decimal Open;
public decimal High;
public decimal Low;
public decimal Close;
public decimal Vwap;
public decimal Volume;
public int Count;
}
I have a standard deserializer class which works for all other calls I am using to the same API, but I cannot get this call to work. When I retrieve OHLCResponse object,I don't get an error, and "Result.Last" is always populated, but the expected array of OHLC items in "Result.GetHistory" is always empty/null. I know that the data has been returned successfully since I can see the data in the variable returned from the WebRequest that I am then passing to the deserializer function, so it must be that I have these classes laid out incorrectly I guess.
Can anyone see what I'm doing wrong?
Many thanks in advance, Dave
The object you posted isn't valid JSON. The outside curly braces are missing. So I am going to assume it should look like this:
{
"error": [],
"result": {
"MANAEUR": [
[1619042400, "1.11200", "1.13488", "1.08341", "1.10077", "1.09896", "58878.56534370", 137],
[1619046000, "1.09767", "1.12276", "1.08490", "1.11097", "1.10456", "25343.25910419", 77],
],
"last": 1619118000
}
}
Anonymous Deserialization
The first method you could do, which may be a tad kludgy since you have to deserialize twice, is use anonymous deserialization.
Let's start by defining some models:
public sealed class OHLCModel
{
public long Time { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public decimal Vwap { get; set; }
public decimal Volume { get; set; }
public int Count { get; set; }
}
public sealed class ResultModel
{
[JsonIgnore]
public IEnumerable<OHLCModel> Manaeur { get; set; }
[JsonProperty("last")]
public long Last { get; set; }
}
public sealed class RootModel
{
[JsonProperty("error")]
public List<string> Error { get; set; }
[JsonProperty("result")]
public ResultModel Result { get; set; }
}
As you can see we are ignoring the Manaeur object when serialization happens.
To make this method work, we'd do this:
var json = System.IO.File.ReadAllText(#"c:\users\andy\desktop\test.json");
// First, just grab the object that has the mixed arrays.
// This creates a "template" of the format of the target object
var dto = JsonConvert.DeserializeAnonymousType(json, new
{
Result = new
{
Manaeur = new List<List<object>>()
}
});
// Next, deserialize the rest of it
var fullObject = JsonConvert.DeserializeObject<RootModel>(json);
// transfer the DTO using a Select statement
fullObject.Result.Manaeur = dto.Result.Manaeur.Select(x => new OHLCModel
{
Time = Convert.ToInt64(x[0]),
Open = Convert.ToDecimal(x[1]),
High = Convert.ToDecimal(x[2]),
Low = Convert.ToDecimal(x[3]),
Close = Convert.ToDecimal(x[4]),
Vwap = Convert.ToDecimal(x[5]),
Volume = Convert.ToDecimal(x[6]),
Count = Convert.ToInt32(x[7])
});
This isn't the most ideal solution as you are tightly coupling to the model in a few spots. The ideal way to do this would be to make a custom JsonSerializer.
Use a Custom JsonConverter
First thing we do is change your ResultModel to look like this:
public sealed class ResultModel
{
[JsonConverter(typeof(ManaeurJsonConverter)), JsonProperty("MANAEUR")]
public IEnumerable<OHLCModel> Manaeur { get; set; }
[JsonProperty("last")]
public long Last { get; set; }
}
Then implement a JsonConverter:
public sealed class ManaeurJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => false; // this will never get called
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var lst = JArray.Load(reader).ToObject<List<List<object>>>();
return lst.Select(x => new OHLCModel
{
Time = Convert.ToInt64(x[0]),
Open = Convert.ToDecimal(x[1]),
High = Convert.ToDecimal(x[2]),
Low = Convert.ToDecimal(x[3]),
Close = Convert.ToDecimal(x[4]),
Vwap = Convert.ToDecimal(x[5]),
Volume = Convert.ToDecimal(x[6]),
Count = Convert.ToInt32(x[7])
});
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ // we don't need to write
throw new NotImplementedException();
}
}
You can then simply call it as so:
var json = System.IO.File.ReadAllText(#"c:\users\andy\desktop\test.json");
var fullObject = JsonConvert.DeserializeObject<RootModel>(json);
Your JSON is not valid, I had to modify it to make it valid JSON (https://jsonformatter.org/). I added the root brackets and removed the comma delimter after the second inner array entry.
Valid JSON:
{
"error":[],
"result":
{
"MANAEUR":[
[1619042400,"1.11200","1.13488","1.08341","1.10077","1.09896","58878.56534370",137],
[1619046000,"1.09767","1.12276","1.08490","1.11097","1.10456","25343.25910419",77]
],
"last":1619118000
}
}
After updating the JSON, I used Visual Studio's 'Paste Special' to generate C# objects from the JSON. The following classes were created.
public class RootObject
{
[JsonProperty("error")]
public object[] Error { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
}
public class Result
{
[JsonProperty("MANAEUR")]
public object[][] Manaeur { get; set; }
[JsonProperty("last")]
public int Last { get; set; }
}
With the above JSON and classes, I used the following to deserialize the JSON.
string json = "{\"error\":[],\"result\":{\"MANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
var obj = JsonConvert.DeserializeObject<RootObject>(json);
EDIT:
To handle the MANAEUR property where the key label can be different.
Create a JsonConverter...
public class ManaeurConverter : JsonConverter
{
private Dictionary<string, string> propertyMappings { get; set; }
public ManaeurConverter()
{
this.propertyMappings = new Dictionary<string, string>
{
{"NOTMANAEUR","MANAEUR"}
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object instance = Activator.CreateInstance(objectType);
var props = objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject jo = JObject.Load(reader);
foreach (JProperty jp in jo.Properties())
{
if (!propertyMappings.TryGetValue(jp.Name, out var name))
name = jp.Name;
PropertyInfo prop = props.FirstOrDefault(pi =>
pi.CanWrite && pi.GetCustomAttribute<JsonPropertyAttribute>().PropertyName == name);
prop?.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
}
return instance;
}
public override bool CanConvert(Type objectType)
{
return objectType.GetTypeInfo().IsClass;
}
public override bool CanWrite => false;
}
... Add the JsonConverter attribute to the class...
[JsonConverter(typeof(ManaeurConverter))]
public class Result
{
[JsonProperty("MANAEUR")]
public object[][] Manaeur { get; set; }
[JsonProperty("last")]
public int Last { get; set; }
}
... and parse like so...
string json_Manaeur = "{\"error\":[],\"result\":{\"MANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
string json_Not_Manaeur = "{\"error\":[],\"result\":{\"NOTMANAEUR\":[[1619042400,\"1.11200\",\"1.13488\",\"1.08341\",\"1.10077\",\"1.09896\",\"58878.56534370\",137],[1619046000,\"1.09767\",\"1.12276\",\"1.08490\",\"1.11097\",\"1.10456\",\"25343.25910419\",77]],\"last\":1619118000}}";
var objManaeur = JsonConvert.DeserializeObject<RootObject>(json_Manaeur);
var objNotManaeur = JsonConvert.DeserializeObject<RootObject>(json_Not_Manaeur);

C# How to deserialize the Json to a generic entity use base-class?

I need to convert JSON object to entity,
I have many entities and I don't want to write my code some times, so I built an entity-base class and I want to do deserialize to entity (without know which derived-entity call to the base-entity).
Can I do it?
This is my base class (It is abstract class)
public abstract class AbstractEntity
{
EntityState EntityState { get; set; }
DateTime CreatedDate { get; set; }
DateTime? ModifiedDate { get; set; }
string CreatedBy { get; set; }
string ModifiedBy { get; set; }
public EntityState getEntityState()
{
return EntityState;
}
public void SetEntityState(EntityState entityState)
{
EntityState = entityState;
}
}
The first ent:
public class TABLE1: AbstractEntity
{
public TABLE1();
public string ID{ get; set; }
public string ADDRESS{ get; set; }
public virtual ICollection<TABLE2> TABLE2 { get; set; }
}
The second ent:
public class TABLE2: AbstractEntity
{
public TABLE2();
public string ID{ get; set; }
public string ADDRESS{ get; set; }
public virtual TABLE1 TABLE1{ get; set; }
}
The duplicate linked is probably a better general-purpose solution:
public class AbstractEntityConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(AbstractEntity);
}
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
JObject item = JObject.Load(reader);
var type = item["TYPE"].Value<string>();
switch (type)
{
case "TABLE1":
return item.ToObject<TABLE1>();
case "TABLE2":
return item.ToObject<TABLE2>();
default:
return null;
}
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Usage:
string json = "{\"TYPE\":\"TABLE1\",\"CreatedDate\":\"2018-06-10T08:00:00.000Z\",\"CreatedBy\":\"John\",\"ID\":\"1\",\"ADDRESS\":\"1 Road Street\",\"TABLE2\":[{\"CreatedDate\":\"2018-06-10T08:00:00.000Z\",\"CreatedBy\":\"John\",\"ID\":\"2\",\"ADDRESS\":\"2 Road Street\"}]}";
var settings = new JsonSerializerSettings()
{
Converters = new List<JsonConverter>()
{
new AbstractEntityConverter()
}
};
var obj = JsonConvert.DeserializeObject<AbstractEntity>(json, settings);
Of course, you can define your JsonSettings at a central location so that you don't have to keep writing the declaration every time you use it.
P.S. I've opted to assume a "type" property since you didn't show your JSON, or your method of determining which class to deserialize to. Replace with your own logic as needed.
Try it online
You can use JObject from Newtonsoft.Json library. This is the site https://www.newtonsoft.com/json to refer on how to use it. And, a lot of code samples as well can be found here https://www.newtonsoft.com/json/help/html/Samples.htm.
For example:
using Newtonsoft.Json.Serialization;
public void Foo(string jsonData){
var objData = (JObject)JsonConvert.DeserializeObject(jsonData); // Deserialize json data
dynamic jObject = new JObject();
jObject.ID = objData.Value<string>("ID");
jObject.Address = objData.Value<string>("Address");
jObject.TABLE2 = objData.Value<JArray>("TABLE2");
}
In the above code sample, jObject which has a dynamic type that can be converted to which type you want.
Hope this helps.

De-Serialize JSON to different elements based on content of element

I am trying to parse into different items a JSON file that has items with the following example content:
{
"PM00000001": { "description": "Manufacturing","cost": -1,"group":"Manufacturing","WeldAngleDegrees": 60},
"PM00000010": {"description": "Plate Roll","cost": 90,"unit": "hr","group": "Roll","setup": 0.5,"speed": 0.4},
"PM00000011": {"description": "Weld SAW","cost": 90,"unit": "hr","group": "Weld","width": 0.5,"thickness": 50}
}
Each item has a description, cost and group. The rest of the attributes depend on the group. In the example above Manufacturing has "WeldAngleDegrees", Roll has setup and speed, and Weld has width and thickness.
I am trying to use JSON.NET to parse this file.
Right now I am doing this:
string text = System.IO.File.ReadAllText(ofd.FileName);
Dictionary<string, Item> deserializedProduct = JsonConvert.DeserializeObject<Dictionary<string, Item>>(text, new ItemConverter());
with
public class Item
{
public string description { get; set; }
public double cost { get; set; }
public string group { get; set; }
}
public class ManufacturingItem : Item
{
public string WeldAngleDegrees { get; set; }
}
public class ItemConverter : CustomCreationConverter<Item>
{
public override Item Create(Type objectType)
{
return new ManufacturingItem();
}
}
Is there a way in ItemConverter to figure out which "group" the item belongs to to create the correct item type?
Is there an easier way to do this?
Instead of deriving your ItemConverter from CustomCreationConverter<T>, derive it from JsonConverter; then you will have access to the JSON via the reader. You can load the object data into a JObject, then inspect the group property to determine which class to create. Here is how the code might look:
public class ItemConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Item);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
string group = (string)jo["group"];
if (group == "Manufacturing")
{
return jo.ToObject<ManufacturingItem>();
}
else if (group == "Roll")
{
return jo.ToObject<RollItem>();
}
else if (group == "Weld")
{
return jo.ToObject<WeldItem>();
}
throw new JsonSerializationException("Unexpected item (group) type");
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Fiddle: https://dotnetfiddle.net/8ZIubu
Just deserialize your json to a dictionary, and interpret the values according to the value of group.
var dict = JsonConvert.DeserializeObject<Dictionary<string, MyItem>>(json);
public class MyItem
{
public string Description { get; set; }
public int Cost { get; set; }
public string Group { get; set; }
public int WeldAngleDegrees { get; set; }
public string Unit { get; set; }
public double Width { get; set; }
public int Thickness { get; set; }
public double Speed { get; set; }
public double Setup { get; set; }
}

How should I parse JSON which has its keys and values' accents escaped without affecting the escapings in the field values?

Querying the Stack Overflow websockets with 155-questions-active I get the following (malformatted) JSON:
{
"action":"155-questions-active",
"data":
"{
\"siteBaseHostAddress\":\"stackoverflow.com\",
\"id\":23747905,
\"titleEncodedFancy\":\"Load sqlite extension in Django\",
\"bodySummary\":\"I have built a sqlite <snip>\",
\"tags\":[\"django\",\"sqlite\",\"pysqlite\"],
\"lastActivityDate\":1400544795,
\"url\":\"http://stackoverflow.com/questions/23747905/<snip>\",
\"ownerUrl\":\"http://stackoverflow.com/users/1311165/pro-chats\",
\"ownerDisplayName\":\"Pro Chats\",
\"apiSiteParameter\":\"stackoverflow\"
}"
}
After applying some fixes
private string MakeJsonCapable(string input)
{
input = input.Trim();
input = input.Replace("data\":\"", "data\":");
input = input.Remove(input.LastIndexOf("\""), 1);
input = input.Replace("\\", string.Empty);
return input;
}
I get to this result:
{
"action": "155-questions-active",
"data": {
"siteBaseHostAddress": "stackoverflow.com",
"id": 23747905,
"titleEncodedFancy": "Load sqlite extension in Django",
"bodySummary": "I have built a sqlite <snip>",
"tags": [
"django",
"sqlite",
"pysqlite"
],
"lastActivityDate": 1400544795,
"url": "http:\/\/stackoverflow.com\/questions\/23747905\/<snip>",
"ownerUrl": "http:\/\/stackoverflow.com\/users\/1311165\/pro-chats",
"ownerDisplayName": "Pro Chats",
"apiSiteParameter": "stackoverflow"
}
}
Which is now acceptable JSON (I'm using some online JSON format tool to verify this) that gets parsed perfectly by JSON.NET.
The problem occurs when a value (so far I've only seen it in bodySummary but I suspect titleEncodedFancy is also likely to have this) contains a ". The literal value that is being passed before making it Json-able is \\\"Compliant Solution\\\": 3 backslashes and an accent.
Note that this is the literal value and does not include any backslashes from the debugger: this is taken directly from the textview; the watch variable shows 7 backslashes.
Obviously this is a problem because now my bodySummary contains an unescaped " which will corrupt the deserializing. For this reason I can't create a custom JsonConverter to escape them myself either since it won't get the right values in the first place.
How can I remove the unwanted backslashes that appear in front of the accents that signify the start and end of a field's name and its value?
Alternatively: maybe I am parsing the data field incorrectly in the first place. If so: what is the correct way?
What you have here is data that has been serialized to a string, placed inside another object and then serialized a second time. To get everything back out correctly, you can reverse the process. Define two classes, one for the outer serialization and one for the inner:
class Outer
{
public string Action { get; set; }
public string Data { get; set; }
}
class Inner
{
public string SiteBaseHostAddress { get; set; }
public int Id { get; set; }
public string TitleEncodedFancy { get; set; }
public string BodySummary { get; set; }
public string[] Tags { get; set; }
public int LastActivityDate { get; set; }
public string Url { get; set; }
public string OwnerUrl { get; set; }
public string OwnerDisplayName { get; set; }
public string ApiSiteParameter { get; set; }
}
Then deserialize like this:
Outer outer = JsonConvert.DeserializeObject<Outer>(json);
Inner inner = JsonConvert.DeserializeObject<Inner>(outer.Data);
When you do this, do NOT apply the "fixes" to the input string. Let the JSON parser do its job.
EDIT
If you want to keep the parent-child relationship, you'll need a custom JsonConverter to handle the deserialization of the child object. To do this, you first need to change the definition of the outer class to this:
class Outer
{
public string Action { get; set; }
[JsonConverter(typeof(InnerConverter))]
public Inner Data { get; set; }
}
Create the InnerConverter class like this:
class InnerConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Inner));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
return JsonConvert.DeserializeObject<Inner>(token.ToString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And finally, you can deserialize like this:
Outer outer = JsonConvert.DeserializeObject<Outer>(json);
Following Brian Rogers' suggestion I created a simple converter which handles it all for me:
Response
public sealed class Response
{
[JsonProperty("action")]
public string Action { get; internal set; }
[JsonProperty("data")]
[JsonConverter(typeof (DataConverter))]
public Data Data { get; internal set; }
}
Data
public sealed class Data
{
[JsonProperty("siteBaseHostAddress")]
public string SiteBaseHostAddress { get; internal set; }
[JsonProperty("id")]
public string Id { get; internal set; }
[JsonProperty("titleEncodedFancy")]
public string TitleEncodedFancy { get; internal set; }
[JsonProperty("bodySummary")]
public string BodySummary { get; internal set; }
[JsonProperty("tags")]
public IEnumerable<string> Tags { get; internal set; }
[JsonProperty("lastActivityDate")]
[JsonConverter(typeof (EpochTimeConverter))]
public DateTime LastActivityDate { get; internal set; }
[JsonProperty("url")]
[JsonConverter(typeof (UriConverter))]
public Uri QuestionUrl { get; internal set; }
[JsonProperty("ownerUrl")]
[JsonConverter(typeof (UriConverter))]
public Uri OwnerUrl { get; internal set; }
[JsonProperty("ownerDisplayName")]
public string OwnerDisplayName { get; internal set; }
[JsonProperty("apiSiteParameter")]
public string ApiSiteParameter { get; internal set; }
}
DataConverter
internal sealed class DataConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof (string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
var value = reader.Value as string;
return JsonConvert.DeserializeObject<Data>(value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Now I can deserialize it entirely with
var responseObject = JsonConvert.DeserializeObject<Response>(result);

Deserialize JSON String Nested Dictionary

I am trying to use Riot games REST API to make a webapp in C#. I am fine with making the requests using RESTSharp but am having some problems using JSON.Net to convert the returned Json to an object. My request returns a JSON string for example:
{\"dyrus\":{\"id\":4136713,\"name\":\"Dyrus\",\"profileIconId\":23,\"summonerLevel\":1,\"revisionDate\":1376908220000}}
I want to deserialize this into an object that has attributes: id, name, profileIconID, summonerLevel and revisionDate.
The problem I am having is that the information is being deserialized as a string because the Dictionary is nested. What is the best way to just retrieve the nested Dictionary portion of the string: {\"id\":4136713,\"name\":\"Dyrus\",\"profileIconId\":23,\"summonerLevel\":1,\"revisionDate\":1376908220000} and convert it into an object?
Thanks for your help!
Edit:
Here is what I have tried:
public class LeagueUser
{
public LeagueUser(string json)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string jsonString = (string)serializer.DeserializeObject(json);
LeagueUser test = (LeagueUser)serializer.DeserializeObject(jsonString);
}
public int id { get; set; }
public string name { get; set; }
public long revisionDate { get; set; }
}
You don't need the constructor, change LeagueUser class to this
public class LeagueUser
{
public int id { get; set; }
public string name { get; set; }
public long revisionDate { get; set; }
}
and use Json.NET to deserialize the json into a Dictionary<string, LeagueUser>
string jsonStr = "{\"dyrus\":{\"id\":4136713,\"name\":\"Dyrus\",\"profileIconId\":23,\"summonerLevel\":1,\"revisionDate\":1376908220000}}";
var deserializedObject = JsonConvert.DeserializeObject<Dictionary<string, LeagueUser>>(jsonStr);
You can get the LeagueUser object this way
LeagueUser leagueUser = deserializedObject["dyrus"];
You can achieve what you want by creating custom converter for your LeagueUser class:
public class LeagueUserConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(LeagueUser) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!CanConvert(objectType)) return null;
var jObject = JObject.Load(reader);
var user = new LeagueUser
{
Id = Convert.ToInt64(jObject["dyrus"]["id"]),
Name = jObject["dyrus"]["name"].ToString(),
ProfileIconId = Convert.ToInt32(jObject["dyrus"]["profileIconId"]),
SummonerLevel = Convert.ToInt32(jObject["dyrus"]["summonerLevel"]),
RevisionDate = Convert.ToInt64(jObject["dyrus"]["revisionDate"])
};
return user;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Next you need to decorate your class with the defined converter:
[JsonConverter(typeof(LeagueUserConverter))]
public class LeagueUser
{
public long Id { get; set; }
public string Name { get; set; }
public int ProfileIconId { get; set; }
public int SummonerLevel { get; set; }
public long RevisionDate { get; set; }
}
And wherever you need call DeserializeObject method:
var user = JsonConvert.DeserializeObject<LeagueUser>(json);
where the json variable is the json string you posted in your question.

Categories

Resources