I am having a weird problem with serializing data using json.net. Basically, I am trying to rename the names "Key" and "Value" in the outgoing json to be something more descriptive. In particular, I want the "key" associated with IRequest to be called "Request", and the value of IQuoteTimeSeries to be "DataSeries"
Please note: this will not deserialize. It is used only when analyzing data on a web page.
The data repository object that I am serializing is the Dictionary<IRequest, IQuoteTimeSeries> . IRequest represents a specific data request, and IQuoteTimeSeries is an object containing the returned data as SortedDictionary<DateTime, IQuote> . This is a series of data sorted by timestamp. In this example, I have only one item in TimeSeries for brevity, but in most cases there will be many items.
Everything needs to be organized together, serialized and submitted to use JavaScript.
Here is the basic code for these objects;
[JsonArray] public class QuoteRepository : Dictionary<IRequest, IQuoteTimeSeries>, IQuoteRepository { public QuoteRepository() { } public void AddRequest(IRequest request) { if (!this.ContainsKey(request)) { IQuoteTimeSeries tSeries = new QuoteTimeSeries(request); this.Add(request, tSeries); } } public void AddQuote(IRequest request, IQuote quote) { if (!this.ContainsKey(request)) { QuoteTimeSeries tSeries = new QuoteTimeSeries(request); this.Add(request, tSeries); } this[request].AddQuote(quote); } IEnumerator<IQuoteTimeSeries> Enumerable<IQuoteTimeSeries>.GetEnumerator() { return this.Values.GetEnumerator(); } }
The time series of quotes are as follows:
[JsonArray] public class QuoteTimeSeries: SortedDictionary<DateTime, IQuote>, IQuoteTimeSeries { public QuoteTimeSeries(IRequest request) { Request = request; } public IRequest Request { get; } public void AddQuote(IQuote quote) { this[quote.QuoteTimeStamp] = quote; } public void MergeQuotes(IQuoteTimeSeries quotes) { foreach (IQuote item in quotes) { this[item.QuoteTimeStamp] = item; } } IEnumerator<IQuote> IEnumerable<IQuote>.GetEnumerator() { return this.Values.GetEnumerator(); } }
The code used for serialization is pretty simple:
IQuoteRepository quotes = await requests.GetDataAsync(); JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = QuoteRepositoryContractResolver.Instance, NullValueHandling = NullValueHandling.Ignore }; return Json<IQuoteRepository>(quotes, settings);
I added a contract handler to override the property record. The property.PropertyName = code is deleted, and the property names are changed, but the output JSON is not changed.
public class QuoteRepositoryContractResolver : DefaultContractResolver { public static readonly QuoteRepositoryContractResolver Instance = new QuoteRepositoryContractResolver(); protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); if (property.DeclaringType == typeof(KeyValuePair<IRequest, IQuoteTimeSeries>)) { if (property.PropertyName.Equals("Key", StringComparison.OrdinalIgnoreCase)) { property.PropertyName = "Request"; } else if (property.PropertyName.Equals("Value", StringComparison.OrdinalIgnoreCase)) { property.PropertyName = "Data"; } } else if (property.DeclaringType == typeof(KeyValuePair<DateTime, IQuote>)) { if (property.PropertyName.Equals("Key", StringComparison.OrdinalIgnoreCase)) { property.PropertyName = "TimeStamp"; } else if (property.PropertyName.Equals("Value", StringComparison.OrdinalIgnoreCase)) { property.PropertyName = "Quote"; } } return property; } }
JSON output is odd. The Key and Value elements have not completely changed, although I changed their names in the code.
[ { "Key": { "QuoteDate": "2016-05-12T00:00:00-04:00", "QuoteType": "Index", "Symbol": "SPY", "UseCache": true }, "Value": [ { "Key": "2016-05-11T16:00:01-04:00", "Value": { "Description": "SPDR S&P 500", "High": 208.54, "Low": 206.50, "Change": -1.95, "ChangePer": -0.94, "Price": 206.50, "QuoteTimeStamp": "2016-05-11T16:00:01-04:00", "Symbol": "SPY" } } ] }, { "Key": { "QuoteDate": "2016-05-12T00:00:00-04:00", "QuoteType": "Stock", "Symbol": "GOOG", "UseCache": true }, "Value": [ { "Key": "2016-05-11T16:00:00-04:00", "Value": { "Description": "Alphabet Inc.", "High": 724.48, "Low": 712.80, "Change": -7.89, "ChangePer": -1.09, "Price": 715.29, "QuoteTimeStamp": "2016-05-11T16:00:00-04:00", "Symbol": "GOOG" } } ] } ]
Does anyone know how to change the "Key" and "Value" elements correctly?