gpt4 book ai didi

c# - 使用JSON.NET序列化复杂字典时更改 'Key'和 'Value'的名称

转载 作者:太空狗 更新时间:2023-10-29 23:29:25 29 4
gpt4 key购买 nike

我在使用 json.net 序列化数据时遇到了一个奇怪的问题。主要是,我试图将传出的 json 中的“键”和“值”名称重命名为更具描述性。具体来说,我希望将与 IRequest 相关的“Key”称为“Request”,将 IQuoteTimeSeries 的“Value”称为“DataSeries”

注意,这不会被反序列化。仅用于网页上的数据分析。

我正在序列化的数据存储库对象是一个 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);

我添加了一个契约(Contract)解析器,目的是覆盖属性写入。 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&amp;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"
}
}
]
}
]

有谁知道如何正确更改“键”和“值”项?

最佳答案

解决此问题的一种方法是为基于字典的类使用自定义 JsonConverter。代码实际上非常简单。

public class CustomDictionaryConverter<K, V> : JsonConverter
{
private string KeyPropertyName { get; set; }
private string ValuePropertyName { get; set; }

public CustomDictionaryConverter(string keyPropertyName, string valuePropertyName)
{
KeyPropertyName = keyPropertyName;
ValuePropertyName = valuePropertyName;
}

public override bool CanConvert(Type objectType)
{
return typeof(IDictionary<K, V>).IsAssignableFrom(objectType);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IDictionary<K, V> dict = (IDictionary<K, V>)value;
JArray array = new JArray();
foreach (var kvp in dict)
{
JObject obj = new JObject();
obj.Add(KeyPropertyName, JToken.FromObject(kvp.Key, serializer));
obj.Add(ValuePropertyName, JToken.FromObject(kvp.Value, serializer));
array.Add(obj);
}
array.WriteTo(writer);
}

public override bool CanRead
{
get { return false; }
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

当需要序列化时,将转换器添加到 JsonSerializerSettings,如下所示:

JsonSerializerSettings settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new CustomDictionaryConverter<IRequest, IQuoteTimeSeries>("Request", "Data"),
new CustomDictionaryConverter<DateTime, IQuote>("TimeStamp", "Quote")
},
Formatting = Formatting.Indented
};

string json = JsonConvert.SerializeObject(repo, settings);

fiddle :https://dotnetfiddle.net/roHEtx

关于c# - 使用JSON.NET序列化复杂字典时更改 'Key'和 'Value'的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37181982/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com