我无法使用JSON.NET将某个JSON字符串映射到Dictionary<T, T2>
。
我的JSON字符串如下所示:
{
"map_waypoint": { "file_id": 157353, "signature": "32633AF8ADEA696A1EF56D3AE32D617B10D3AC57" },
"map_waypoint_contested": { "file_id": 102349, "signature": "5EF051273B40CFAC4AEA6C1F1D0DA612C1B0776C" },
"map_waypoint_hover": { "file_id": 157354, "signature": "95CE3F6B0502232AD90034E4B7CE6E5B0FD3CC5F" }
}
我没有为每个对象创建3个相同的类,而是创建了适用于所有对象的1个类Asset
:
public class Asset
{
/// <summary>
/// Initializes a new instance of the <see cref="Asset"/> class.
/// </summary>
public Asset()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Asset"/> class.
/// </summary>
/// <param name="fileId">The file ID.</param>
/// <param name="signature">The file signature.</param>
[JsonConstructor]
public Asset(string fileId, string signature)
{
this.FileId = fileId;
this.Signature = signature;
}
/// <summary>
/// Gets the file ID to be used with the render service.
/// </summary>
[JsonProperty("file_id")]
public string FileId { get; private set; }
/// <summary>
/// Gets file signature to be used with the render service.
/// </summary>
[JsonProperty("signature")]
public string Signature { get; private set; }
/// <summary>
/// Gets the JSON representation of this instance.
/// </summary>
/// <returns>Returns a JSON <see cref="String"/>.</returns>
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
现在在另一个班级FilesResponse
中,我保留了Files
类型的属性Dictionary<String, Asset>
。
public class FilesResponse
{
/// <summary>
/// Initializes a new instance of the <see cref="FilesResponse"/> class.
/// </summary>
public FilesResponse()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="FilesResponse"/> class.
/// </summary>
/// <param name="files">A collection of assets by their name.</param>
[JsonConstructor]
public FilesResponse(Dictionary<string, Asset> files)
{
this.Files = files;
}
/// <summary>
/// Gets the collection of assets by their name.
/// </summary>
[JsonProperty]
public Dictionary<string, Asset> Files { get; private set; }
/// <summary>
/// Gets the JSON representation of this instance.
/// </summary>
/// <returns>Returns a JSON <see cref="String"/>.</returns>
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
问题是我不太确定如何让JSON.NET知道我的JSON字符串中的数据应该进入字典...?
理想情况下,我希望能够做到这一点:
var filesResponse = JsonConvert.DeserializeObject<FilesResponse>(jsonString);
foreach (var file in filesResponse.Files)
{
Console.WriteLine("Name = {0}, ID = {1}", file.Key, file.Value.FileId);
}
我能以某种方式完成这项工作吗?
答案 0 :(得分:0)
如果您想拥有GUID,则需要实现自己的转换器。我最终得到了这样的东西。
public class StringGuidConverter: JsonConverter {
public override bool CanConvert(Type objectType) {
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
return new Guid((string)reader.Value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
writer.WriteValue(((Guid)value).ToString("N"));
}
}
public class Asset {
/// <summary>
/// Initializes a new instance of the <see cref="Asset"/> class.
/// </summary>
public Asset() {
}
/// <summary>
/// Initializes a new instance of the <see cref="Asset"/> class.
/// </summary>
/// <param name="fileId">The file ID.</param>
/// <param name="signature">The file signature.</param>
[JsonConstructor]
public Asset(string fileId, Guid signature) {
this.FileId = fileId;
this.Signature = signature;
}
/// <summary>
/// Gets the file ID to be used with the render service.
/// </summary>
[JsonProperty("file_id")]
public string FileId { get; private set; }
/// <summary>
/// Gets file signature to be used with the render service.
/// </summary>
[JsonProperty("signature")]
[JsonConverter(typeof(StringGuidConverter))]
public Guid Signature { get; private set; }
/// <summary>
/// Gets the JSON representation of this instance.
/// </summary>
/// <returns>Returns a JSON <see cref="String"/>.</returns>
public override string ToString() {
return JsonConvert.SerializeObject(this);
}
}
public class FilesResponse {
/// <summary>
/// Initializes a new instance of the <see cref="FilesResponse"/> class.
/// </summary>
public FilesResponse() {
}
/// <summary>
/// Initializes a new instance of the <see cref="FilesResponse"/> class.
/// </summary>
/// <param name="files">A collection of assets by their name.</param>
[JsonConstructor]
public FilesResponse(Dictionary<string, Asset> files) {
this.Files = files;
}
/// <summary>
/// Gets the collection of assets by their name.
/// </summary>
[JsonProperty]
public Dictionary<string, Asset> Files { get; private set; }
/// <summary>
/// Gets the JSON representation of this instance.
/// </summary>
/// <returns>Returns a JSON <see cref="String"/>.</returns>
public override string ToString() {
return JsonConvert.SerializeObject(this);
}
}
class Test {
public static void Run() {
var json = @"{
""map_waypoint"": { ""file_id"": 157353, ""signature"": ""32633AF8ADEA696AE32D617B10D3AC57"" },
""map_waypoint_contested"": { ""file_id"": 102349, ""signature"": ""32633AF8ADEA696AE32D617B10D3AC57"" },
""map_waypoint_hover"": { ""file_id"": 157354, ""signature"": ""32633AF8ADEA696AE32D617B10D3AC57"" }
}";
var result2 = JsonConvert.DeserializeObject<FilesResponse>(json);
var result3 = new FilesResponse(JsonConvert.DeserializeObject<Dictionary<string, Asset>>(json));
}
}
Unfotunatelly result2
不起作用
修改强> 顺便说一句。你的数据不正确。 GUID长度为32个字符,长度为40个字符。这就是我必须修改测试数据的原因。
<强> EDIT2 强>
我会使FilesResponse
继承自字典,如下所示:
public class FilesResponse2: Dictionary<string, Asset>
{
/// <summary>
/// Initializes a new instance of the <see cref="FilesResponse"/> class.
/// </summary>
public FilesResponse2() {
}
/// <summary>
/// Gets the collection of assets by their name.
/// </summary>
public Dictionary<string, Asset> Files { get { return this; } }
/// <summary>
/// Gets the JSON representation of this instance.
/// </summary>
/// <returns>Returns a JSON <see cref="String"/>.</returns>
public override string ToString() {
return JsonConvert.SerializeObject(this);
}
}
// deserialization:
var result22 = JsonConvert.DeserializeObject<FilesResponse2>(json);