gpt4 book ai didi

c# - newtonsoft json.net - 使用值元组键反序列化字典

转载 作者:行者123 更新时间:2023-12-05 03:59:20 25 4
gpt4 key购买 nike

反序列化具有值元组键的字典时出现错误。我认为它将元组转换为字符串,然后无法将其反序列化为键:

Newtonsoft.Json.JsonSerializationException
HResult=0x80131500
Message=Could not convert string '(1, 2)' to dictionary key type 'System.ValueTuple`2[System.Int32,System.Int32]'. Create a TypeConverter to convert from the string to the key type object. Path 'Types['(1, 2)']', line 1, position 49.
Source=Newtonsoft.Json
StackTrace:
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at ConsoleApp.Program.Main(String[] args) in D:\Open Source\JsonSerilization\ConsoleApp\ConsoleApp\Program.cs:line 65

Inner Exception 1:
JsonSerializationException: Error converting value "(1, 2)" to type 'System.ValueTuple`2[System.Int32,System.Int32]'. Path 'Types['(1, 2)']', line 1, position 49.

Inner Exception 2:
ArgumentException: Could not cast or convert from System.String to System.ValueTuple`2[System.Int32,System.Int32].

有没有标准的解决方案?

到目前为止,我似乎需要提供一个自定义转换器;这看起来很乏味。

更新:

这是我要序列化/反序列化的类:

public sealed class Message
{
[JsonConstructor]
internal Message()
{ }

public ISet<(int Id, int AnotherId)> Ids { get; set; }
= new HashSet<(int Id, int AnotherId)>();

public Dictionary<(int Id, int AnotherId), int> Types { get; set; }
= new Dictionary<(int Id, int AnotherId), int>();
}

这里是我使用它的地方:

var message = new Message();
message.Ids.Add((1, 2));
message.Types[(1, 2)] = 3;

var messageStr = JsonConvert.SerializeObject(message);
var messageObj = JsonConvert.DeserializeObject<Message>(messageStr);

最佳答案

就像您在 OP 中已经提到的那样,TypeConverter 在这里对反序列化元组键很有用。但它可能并不像看起来那么乏味。

例如,您可以编写一个简单的 TypeConverter,如下所示。

public class TupleConverter<T1, T2>: TypeConverter 
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context,CultureInfo culture, object value)
{
var key = Convert.ToString(value).Trim('(').Trim(')');
var parts = Regex.Split(key, (", "));
var item1 = (T1)TypeDescriptor.GetConverter(typeof(T1)).ConvertFromInvariantString(parts[0])!;
var item2 = (T2)TypeDescriptor.GetConverter(typeof(T2)).ConvertFromInvariantString(parts[1])!;
return new ValueTuple<T1, T2>(item1, item2);
}
}

现在,您可以执行以下操作。

var dictionary = new Dictionary<(string,string),int>
{
[("firstName1","lastName1")] = 5,
[("firstName2","lastName2")] = 5
};

TypeDescriptor.AddAttributes(typeof((string, string)), new TypeConverterAttribute(typeof(TupleConverter<string, string>)));
var json = JsonConvert.SerializeObject(dictionary);
var result = JsonConvert.DeserializeObject<Dictionary<(string,string),string>>(json);

关于c# - newtonsoft json.net - 使用值元组键反序列化字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57316961/

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