Deseralize JSON with same property different names - c#

The JSON looks like this
{
"123": {
"Type": "IN",
"OUTAgentMACID": "00-14-22-01-23-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5901291
}
},
"124": {
"Type": "OUT",
"OUTAgentMACID": "00-14-22-01-31-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5991291
}
},
"125": {
"Type": "IN",
"INAgentMACID": "00-14-22-01-63-45",
"PlateNumber": {
"Image": "/poll/data/date1/img.png",
"Number": "ABC1234",
"TimeStamp": 6001239
}
}
}
The probable class structure is
public class PlateNumber
{
public string Image { get; set; }
public string Number { get; set; }
public int TimeStamp { get; set; }
}
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
public PlateNumber PlateNumber { get; set; }
}
public class SessionActivity
{
public Dictionary<int, Activity> Activities { get; set; }
}
Helper looks like this
public class helpers : DefaultContractResolver
{
private Dictionary<string, string> PropertyMappings { get; set; }
public helpers()
{
PropertyMappings = new Dictionary<string, string>
{
{"INAgentMACID", "AgentMACID"},
{"OUTAgentMACID", "AgentMACID"},
};
}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName);
return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName);
}
}
Now when I try to deserializing it like this
var settings = new JsonSerializerSettings();
settings.ContractResolver = new helpers();
var activities = JsonConvert.DeserializeObject<SessionActivity>("Some.json"), settings);
the activities is null.
The Problem is AgentMACID Since the JSON have either OUTAgentMACID or INAgentMACID depending on the Type
Please help me design the class for this JSON.

I think it's not directly possible that you have one Property, which represents two Properties of the json- (as I've read here Make JsonPropertyAttribute allow multiple usages on same property)
What I undertsand from this post, you would be forced to have another property, which just "forwards" the value to the one you want.
example:
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
private string AgentMACID2 { set { AgentMACID = value; } } // used to map the other field of json
public PlateNumber PlateNumber { get; set; }
}
in the Contract Resolver you have to mape vias versa as you did. With the second field I added, it might looks as this:
PropertyMappings = new Dictionary<string, string>
{
{"AgentMACID","OUTAgentMACID"},
{"AgentMACID2","INAgentMACID"}
};
And deserialize by this:
var activities = JsonConvert.DeserializeObject<Dictionary<int, Activity>>("json content", settings);

1 - Deserialize a Dictionary from JSON
Based on your json object :
{
"123": {
"Type": "IN",
"OUTAgentMACID": "00-14-22-01-23-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5901291
}
},
"124": {
"Type": "OUT",
"OUTAgentMACID": "00-14-22-01-31-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5991291
}
},
"125": {
"Type": "IN",
"INAgentMACID": "00-14-22-01-63-45",
"PlateNumber": {
"Image": "/poll/data/date1/img.png",
"Number": "ABC1234",
"TimeStamp": 6001239
}
}
}
You can deserialize a dictionary using :
var activities = JsonConvert.DeserializeObject<Dictionary<int, Activity>>("Some.json"), settings);
2.1 - Manage multiple json property names in one C# property
For your second issue you can define your Activity class like this :
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
// Optional: you can rename your property with this property attribute
// [JsonProperty("INAgentMACID")]
public string INAgentMACID { set { AgentMACID = value; } }
// Optional: you can rename your property with this property attribute
// [JsonProperty("OUTAgentMACID")]
public string OUTAgentMACID { set { AgentMACID = value; } }
public PlateNumber PlateNumber { get; set; }
}
2.2 - You can also inherit DefaultContractResolver as you were doing :
public class RenamePropertySerializerContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, HashSet<string>> _ignores;
private readonly Dictionary<Type, Dictionary<string, string>> _renames;
public RenamePropertySerializerContractResolver()
{
_renames = new Dictionary<Type, Dictionary<string, string>>();
}
public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
{
if (!_renames.ContainsKey(type))
_renames[type] = new Dictionary<string, string>();
_renames[type][propertyName] = newJsonPropertyName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
property.PropertyName = newJsonPropertyName;
return property;
}
private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
{
Dictionary<string, string> renames;
if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
{
newJsonPropertyName = null;
return false;
}
return true;
}
}
And finally use you new ContractResolver :
var jsonResolver = new RenamePropertySerializerContractResolver();
jsonResolver.RenameProperty(typeof(Activity), "INAgentMACID", "AgentMACID");
jsonResolver.RenameProperty(typeof(Activity), "OUTAgentMACID", "AgentMACID");
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = jsonResolver;
var activities = JsonConvert.DeserializeObject<IDictionary<int, Activity>>(json, serializerSettings);
sources : https://blog.rsuter.com/advanced-newtonsoft-json-dynamically-rename-or-ignore-properties-without-changing-the-serialized-class/

Related

Deserializing my JSON into POCO not populating few fields

I have below json which I need to deserialize in C# -
{
"clientSettings":[
{
"clientId":12345,
"entries":[
{
"key":"abc",
"value":false
},
{
"key":"def",
"value":false
},
{
"key":"ghi",
"value":false
}
]
},
{
"clientId":9876,
"entries":[
{
"key":"lkmn",
"value":false
}
]
}
],
"productSettings":[
{
"productId":11,
"entries":[
{
"key":"jkl",
"value":true
},
{
"key":"mno",
"value":true
}
]
},
{
"productId":12,
"entries":[
{
"key":"jkl",
"value":true
},
{
"key":"mno",
"value":true
}
]
}
],
"customerSettings":[
{
"key":"enableData",
"value":false
},
{
"key":"minPriceValue",
"value":"10.28"
},
{
"key":"presentData",
"value":"AEGIS"
}
],
"thothTest":{
"9876":[
"K"
],
"5431":[
"A",
"L"
],
"5123":[
"L"
]
},
"osirisTest":{
"7678":[
"K"
]
}
}
Below is the classes I created to deserialzie json into -
public class ProcessHolder : Holder
{
public IDictionary<int, ISet<string>> OsirisTest { get; set; }
public IDictionary<int, ISet<string>> ThothTest { get; set; }
}
public class Holder
{
public IList<Mapping> CustomerSettings { get; set; }
public IList<ClientSettingsMapping> ClientSettings { get; set; }
public IList<ProductSettingsMapping> ProductSettings { get; set; }
}
public class Mapping
{
public string Key { get; set; }
public object Value { get; set; }
}
public class ProductSettingsMapping : Mapping
{
public int ProductId { get; set; }
}
public class ClientSettingsMapping : Mapping
{
public int ClientId { get; set; }
}
I want to load all customerSettings values into CustomerSettings object of Holder class.
Similarly I want to load all clientSettings values into ClientSettings object of Holder class.
Similarly all productSettings values into ProductSettings object of Holder class.
Similarly thothTest values into ThothTest and osirisTest values into OsirisTest object.
I was trying with below code but somehow I am not able to see Key and Value variables being populated inside Mapping class object after deserializing my above json.
private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore
};
public static void Main(string[] args)
{
var jsonContent = File.ReadAllText("/beta/Downloads/test.json");
var config = JsonConvert.DeserializeObject<ProcessHolder>(jsonContent, serializerSettings);
if (config == null)
{
Console.WriteLine("Some Parsing Issue");
}
// using config object here
}
What is wrong I am doing here? I just need to deserialize my json into above classes and give me ProcessHolder object back which I can use later on.
Looking at your JSON, clientSettings and productSettings have entries array. There is no corresponding matching property in your class definition for same.
I would suggest to modify your class definition as per JSON. Try below and see if it helps:
public class ProductSettingsMapping
{
public int ProductId { get; set; }
public IList<Mapping> Entries { get; set; }
}
public class ClientSettingsMapping
{
public int ClientId { get; set; }
public IList<Mapping> Entries { get; set; }
}
Second option - if you are not able to modify classes, you can amend JSON. I am providing sample for clientSettings
{
"clientSettings": [
{
"clientId": 12345,
"key": "abc",
"value": false
},
{
"clientId": 12345,
"key": "def",
"value": false
},
{
"clientId": 12345,
"key": "ghi",
"value": false
},
{
"clientId": 9876,
"key": "lkmn",
"value": false
}
]
}
You can update productSettings accordingly.
Third option is to parse into JObject and then convert to your classes.
A sample for clientSettings
static void Main(string[] args)
{
var json = "{'clientSettings':[{'clientId':12345,'entries':[{'key':'abc','value':false},{'key':'def','value':false},{'key':'ghi','value':false}]},{'clientId':9876,'entries':[{'key':'lkmn','value':false}]}],'productSettings':[{'productId':11,'entries':[{'key':'jkl','value':true},{'key':'mno','value':true}]},{'productId':12,'entries':[{'key':'jkl','value':true},{'key':'mno','value':true}]}],'customerSettings':[{'key':'enableData','value':false},{'key':'minPriceValue','value':'10.28'},{'key':'presentData','value':'AEGIS'}],'thothTest':{'9876':['K'],'5431':['A','L'],'5123':['L']},'osirisTest':{'7678':['K']}}";
var parsed = JObject.Parse(json);
var parsedClientSettings = parsed["clientSettings"];
List<ClientSettingsMapping> clientSettings = new List<ClientSettingsMapping>();
foreach (var parsedClientSetting in parsedClientSettings)
{
var clientId = parsedClientSetting.Value<int>("clientId");
foreach (var entry in parsedClientSetting["entries"])
{
clientSettings.Add(new ClientSettingsMapping { ClientId = clientId, Key = entry["key"].ToString(), Value = entry["value"].ToString() });
}
}
ProcessHolder processHolder = new ProcessHolder() { ClientSettings = clientSettings };
Console.ReadLine();
}
You should define "entries" in both ProductSettingsMapping and ClientSettingsMapping class.
public class ProductSettingsMapping
{
public int ProductId { get; set; }
public IList<Mapping> entries { get; set; }
}
public class ClientSettingsMapping
{
public int ClientId { get; set; }
public IList<Mapping> entries { get; set; }
}

Format each list entry with name JSON

I'm trying to format a List object to JSON in a specific way:
...
{
"MyList": [
"Entry": {
"Id": "1000",
"Name" : "Billy"
}
]
}
...
My problem is that I can't get the "Entry" property name to be written per item in the list.
Here's my C# code:
Entry.cs
[JsonObject(MemberSerialization.OptIn)]
public class Entry
{
[JsonProperty]
public string Id { get; set; }
[JsonProperty]
public string Name { get; set; }
}
List.cs
[JsonObject(MemberSerialization.OptIn)]
public class MyList
{
[JsonProperty]
List<Entry> List = new List<Entry>();
public void Add(Entry param) {
List.Add(param);
}
}
TestController.cs
[HttpPost]
public IHttpActionResult GrabarMarcacion([FromBody] JObject data)
{
MyList lst = new MyList();
lst.Add(new Entry{Id="1000", Name="Billy"});
return Ok(lst);
}
I'm sorry I'm new to JSON and REST, is it even possible to do what I ask? so far I always get something like:
{
"List": {
{
"ID": "1000",
"Name" : "Billy"
},
{
"ID": "1001",
"Name" : "Bob"
}
}
}
I have never used c# but try for Entry.cs :
[JsonObject(MemberSerialization.OptIn)]
public class Entry
{
[JsonProperty]
public object Entry { get; set; }
{
[JsonProperty]
public string Id { get; set; }
[JsonProperty]
public string Name { get; set; }
}
}
From what I understand, you want Entry property name for every item in the list. The simplest way to do this would be by making it a Dictionary:
Renamed Entry.cs to EntryModel.cs
[JsonObject(MemberSerialization.OptIn)]
public class EntryModel
{
[JsonProperty]
public Dictionary<string, string> Entry { get; set; }
}
In List.cs, change the property to MyList. This requires a change to the class name.
[JsonObject(MemberSerialization.OptIn)]
public class MyListModel
{
[JsonProperty]
public List<EntryModel> MyList { get; set; } = new List<EntryModel>();
}
Now in your TestController.cs, you may use:
MyListModel lst = new MyListModel();
lst.MyList.Add(new EntryModel
{
Entry = new Dictionary<string, string> {
{ "Id", "1000" }, { "Name", "Billy" } }
});
lst.MyList.Add(new EntryModel
{
Entry = new Dictionary<string, string> {
{ "Id", "3000" }, {"Name", "ABC" } }
});
This gives the following JSON:
{
"MyList": [
{
"Entry": {
"Id": "1000",
"Name": "Billy"
}
},
{
"Entry": {
"Id": "3000",
"Name": "ABC"
}
}
]
}

Deserialize partial JSON

I'm trying to deserialize some partial JSON received from an old SignalR service.
This is an example of the original JSON:
{
"opt": {
"data": {
"DR": [{
"O": [
null,
"18:46.401",
"RGGW.GWWWR",
"4.1",
19,
"17.852",
"42.455",
"",
null,
"+3.893",
"277",
"306",
"",
"310",
"+0.058",
null
],
"OC": [
"1"
]
},
{
"O": [
null,
"1:41.119",
"GYYG.WWWWW",
"1.0",
2,
"17.561",
"43.485",
"40.073",
null,
"+16.772",
"275",
"291",
"218",
"291",
"+16.772",
null
],
"OC": [
"1"
]
}
]
}
}
}
and this the partial JSON received:
{
"opt": {
"data": {
"DR": {
"1": {
"O": {
"2": "WYYW.WWWWW",
"7": "42.283",
"12": "212"
}
}
}
}
}
}
and these are my classes:
public class DR2
{
[JsonProperty("O")]
public List<object> O { get; set; }
[JsonProperty("OC")]
public List<string> OC { get; set; }
}
public class Data4
{
[JsonProperty("DR")]
public List<DR2> DR { get; set; }
}
public class Opt
{
[JsonProperty("data")]
public Data4 data { get; set; }
}
public class SPFeed
{
[JsonProperty("opt")]
public Opt opt { get; set; }
}
Trying to deserialize I receive the classic error:
JsonSerializationException: Cannot deserialize the current JSON object ... because the type requires a JSON array.
SPFeed partial_opt = JsonConvert.DeserializeObject<SPFeed>(test); // The error above
Also, trying to merge the 2 JSON with the code below, no merge made, but only substitution:
var object1 = JObject.Parse(JsonConvert.SerializeObject(spfeed));
var object2 = JObject.Parse(JsonConvert.SerializeObject(partial_opt));
object1.Merge(object2, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Merge
});
I think because the partial JSON in not a correct array.
Any other method to deserialize?
Resolved:
var obj = JObject.Parse(partialJson);
Opt opt = root.SPFeed.opt;
if (obj["opt"]["data"]["DR"] != null) {
IList<JToken> DR = JObject.Parse(obj["opt"]["data"]["DR"].ToString());
var DRindex = Convert.ToInt32(((JProperty)DR[0]).Name);
var O = ((JProperty)DR[0]).Value;
JToken Otemp = JToken.Parse(O.ToString());
if (Otemp["O"] != null)
{
var Oindex = Otemp["O"];
foreach (JToken item in Oindex)
{
int index = Convert.ToInt32(((JProperty)item).Name);
string value = ((JProperty)item).Value.ToString();
Console.WriteLine("Index {0} Value {1}", index, value);
opt.data.DR[DRindex].O[index] = value;
}
}
};
This may not be the cleanest solution, but if you can detect if the JSON is partial or not, then you could use a Custom Contract Resolver. This would also required some changes to your class structure. Redefining structure as
public interface IData{}
public class Data4Partial:IData
{
[JsonProperty("DR")]
public Dictionary<string,Dictionary<string,Dictionary<string,string>>> Data{get;set;}
}
public class DR2Full:IData
{
[JsonProperty("O")]
public List<object> O { get; set; }
[JsonProperty("OC")]
public List<string> OC { get; set; }
}
public class Data4Full:IData
{
[JsonProperty("DR")]
public List<DR2Full> DR { get; set; }
}
public class Opt
{
[JsonProperty("data")]
public IData data { get; set; }
}
public class SPFeed
{
[JsonProperty("opt")]
public Opt opt { get; set; }
}
The Contract Resolver would aim to replace the PropertyType so that result could be adapted to Partial and Full Json. For example,
public class GenericContractResolver<T> : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property.UnderlyingName == "data")
{
property.PropertyType = typeof(T);
}
return property;
}
}
You could now use it as
var partialResult = JsonConvert.DeserializeObject<SPFeed>(partialJson, new JsonSerializerSettings
{
ContractResolver = new GenericContractResolver<Data4Partial>()
});
Or
var fullResult = JsonConvert.DeserializeObject<SPFeed>(fullJson
, new JsonSerializerSettings
{
ContractResolver = new GenericContractResolver<Data4Full>()
});
Partial Json Output
Complete Json Output

Create a class to build a JSON structure where one of its variables is again has all the variables from its own class (C#)

I've been pondering about this for some time and I think I might just be missing an essential basic coding approach to resolve.
This is what I tried:
class DataSetCommonQuery
{
public string #operator;
public List<DataSetCommonQuery> rules = new List<DataSetCommonQuery>();
}
My expected JSON should be:
{
"payLoad": {
"DataSetCommonQuery": {
"operator": "AND",
"rules": [{
"field": "ENTITY.CIFNumber",
"condition": "<>",
"value": "3123"
},
{
"field": "ENTITY.Country",
"condition": "LIKE",
"value": "USA"
},
{
"operator": "OR",
"rules": [{
"field": "ENTITY.FYEMonth",
"condition": "=",
"value": "May"
},
{
"field": "STATEMENT.ProfitBeforeTax",
"condition": ">=",
"value": 123123
},
{
"field": "STATEMENT.NetSales",
"condition": "<=",
"value": 234234
},
{
"field": "STATEMENT.statementdatekey_",
"condition": "=",
"value": "2019-07-01 12:00:00"
}
]
}
]
}
}
}
You see there is again operator and rules inside the rules. Any thoughts on how should I be declaring the rules variable to be able to get the expected JSON. I am working to build the JSON on C#.
public static DataSetCommonQuery ConvertToJsonObject(string bracketContents)
{
DataSetCommonQuery commonQuery = new DataSetCommonQuery();
string[] operators = splitWithOperator(bracketContents);
commonQuery.#operator = ReturnOperator(bracketContents);
string output;
do
{
//bracketContesnts = getWhatsInsideBrackets(bracketContents);
for (int i = 0; i < splitWithOperator(bracketContents).Length; i++)
{
var jObject = new JObject();
if(!checkIfBracketsExists(operators[i]))
{
List<string> eachCondition = splitEachCondition(operators[i].Trim());
eachCondition.Add(operators[i].Replace(eachCondition[0], "").Replace(eachCondition[1], "").Trim());// Substring(operators1[i].IndexOf(eachCondition[0]), (operators1[i].IndexOf(eachCondition[1]) - operators1[i].IndexOf(eachCondition[0]))));
jObject.Add("field", eachCondition[0]);
jObject.Add("condition", eachCondition[2]);
jObject.Add("value", eachCondition[1]);
}
else if (checkIfBracketsExists(operators[i]))
{
ConvertToJsonObject(getWhatsInsideBrackets(operators[i]));
}
commonQuery.rules.Add(jObject); //THIS LINE SHOWS ERROR CAN NOT CONVERT JOBJECT TO DataSetCommonQuery
}
} while (checkIfBracketsExists(bracketContents));
return commonQuery;
}
Have you tried site converter like this Json2cssharp
This is really a good question, would suggest you to select Newtonsoft.json and do something like this
public partial class StackOverFlow
{
[JsonProperty("payLoad")]
public PayLoad PayLoad { get; set; }
}
public partial class PayLoad
{
[JsonProperty("DataSetCommonQuery")]
public DataSetCommonQuery DataSetCommonQuery { get; set; }
}
public partial class DataSetCommonQuery
{
[JsonProperty("operator")]
public string Operator { get; set; }
[JsonProperty("rules")]
public DataSetCommonQueryRule[] Rules { get; set; }
}
public partial class DataSetCommonQueryRule
{
[JsonProperty("field", NullValueHandling = NullValueHandling.Ignore)]
public string Field { get; set; }
[JsonProperty("condition", NullValueHandling = NullValueHandling.Ignore)]
public string Condition { get; set; }
[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
public string Value { get; set; }
[JsonProperty("operator", NullValueHandling = NullValueHandling.Ignore)]
public string Operator { get; set; }
[JsonProperty("rules", NullValueHandling = NullValueHandling.Ignore)]
public RuleRule[] Rules { get; set; }
}
public partial class RuleRule
{
[JsonProperty("field")]
public string Field { get; set; }
[JsonProperty("condition")]
public string Condition { get; set; }
[JsonProperty("value")]
public Value Value { get; set; }
}
public partial struct Value
{
public long? Integer;
public string String;
public static implicit operator Value(long Integer) => new Value { Integer = Integer };
public static implicit operator Value(string String) => new Value { String = String };
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Value) || t == typeof(Value?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new Value { Integer = integerValue };
case JsonToken.String:
case JsonToken.Date:
var stringValue = serializer.Deserialize<string>(reader);
return new Value { String = stringValue };
}
throw new Exception();
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (Value)untypedValue;
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.String != null)
{
serializer.Serialize(writer, value.String);
return;
}
throw new Exception();
}
public static readonly ValueConverter Singleton = new ValueConverter();
}

How to deserialize JSON to my custom Class

Im new to JSON (and not sure if its the right way to do that), my problem is to deserialize my classes, all models implements this interface:
public interface IPersistent
{
object Id { get; set; }
}
Example of class:
public class ModelTest : IPersistent
{
private int? _id;
public object Id
{
get { return this._id; }
set { this._id = (int?)value; }
}
public string Name { get; set; }
}
Serialize method:
public void SerializeData<T>(T[] data)
{
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
DateFormatHandling = DateFormatHandling.IsoDateFormat
};
var result = JsonConvert.SerializeObject(data, Formatting.Indented, settings);
//more things happen, but not affect serialized data.
}
Deserialize method:
public T[] DeserializeData<T>(string objCached)
{
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
DateFormatHandling = DateFormatHandling.IsoDateFormat
}; //not sure if a need this settings, but...
T[] result = JsonConvert.DeserializeObject<T[]>(objCached, settings); //error here.
return result;
}
Error:
Message=Specified cast is not valid.
objCached data:
[
{
"$id": "1",
"Id": 1000,
"Name": "Name 1"
},
{
"$id": "2",
"Id": 2000,
"Name": "Name 2"
},
{
"$id": "3",
"Id": 3000,
"Name": "Name 3"
},
{
"$id": "4",
"Id": 4000,
"Name": "Name 4"
}
]
I tried validate JSON result using:
http://json2csharp.com/
Result:
public class RootObject
{
public string __invalid_name__$id { get; set; }
public int Id { get; set; }
public string Name { get; set; }
}
I'm looking for something that changes just the methods (Serialize and Deseriaize), can't change ALL my models (its a legacy without any unit test).
All you need to do is changing the set method of Id property. (Because value is long when read from json, which can not be casted toint?)
public class ModelTest : IPersistent
{
private int? _id;
public object Id
{
get { return this._id; }
set { this._id = new Nullable<int>((int)(long)value); }
}
public string Name { get; set; }
}

Categories