我遇到了使用json.net序列化數據的奇怪問題。主要是,我試圖將傳出的json中的'Key'和'Value'名稱重新命名爲更具描述性的名稱。具體來說,我希望將與IRequest相關的'Key'稱爲'Request',將IQuoteTimeSeries'Value''DataSeries'當使用JSON.NET序列化複雜詞典時更改'Key'和'Value'的名稱
注意,這不會被反序列化。它僅用於網頁上的數據分析。
我正在序列化的數據存儲庫對象是一個Dictionary<IRequest, IQuoteTimeSeries>
對象。 IRequest代表對數據的特定請求,IQuoteTimeSeries是包含返回數據的對象,如SortedDictionary<DateTime, IQuote>
。這是按時間戳排序的一系列數據。在這個例子中,爲了簡潔,我只在TimeSeries中有一個項目,但是在大多數情況下會有很多項目。
一切都需要組織在一起,序列化併發送出去供JavaScript使用。
這是這些對象的基本代碼;
[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();
}
}
報價時間系列看起來像這樣;
[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();
}
}
用於序列化此代碼是相當簡單:
IQuoteRepository quotes = await requests.GetDataAsync();
JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = QuoteRepositoryContractResolver.Instance,
NullValueHandling = NullValueHandling.Ignore
};
return Json<IQuoteRepository>(quotes, settings);
我加了一個合同與解析器重寫財產寫作的意圖。正在命中property.PropertyName =
代碼並且屬性名稱正在更改,但輸出JSON不受影響。
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是奇數。儘管我確實在代碼中更改了名稱,但Key和Value項目完全不變。
[
{
"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"
}
}
]
}
]
有誰知道如何正確地更改'鑰匙'和'價值'項目?
@Brian Rogers謝謝你的清理。我的打字技巧在凌晨4:00並不總是那麼棒。 :-) – drobertson
不用擔心,男人。 –