服务器返回的JSON字符串值是URL查询字符串:
{
"parameters": "key1=value1&key2=value2"
}
我设置了一个属性来接收它,并在反序列化过程中将其转换为Dictionary
:
具有JsonConverter
属性的属性:
[JsonConverter(typeof(QueryStringToDictionaryJsonConverter))]
public Dictionary<string, string> Parameters { get; set; }
转换器:
public class QueryStringToDictionaryJsonConverter : JsonConverter<Dictionary<string, string>> {
public override Dictionary<string, string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var queryString = reader.GetString();
if (string.IsNullOrEmpty(queryString)) return null;
return QueryHelpers.ParseQuery(queryString).ToDictionary(e => e.Key, e => string.Join(",", e.Value.ToArray()));
}
...
}
这应该有效。
但这还没到达我的转换器。
据我所知,JsonSerializer.DeserializeAsync<T>(myJson)
看到属性的类型为Dictionary
,因此它尝试自行解析值,并失败(结果异常是尝试GetEnumerable()
等时使用“无效类型转换”)。我的转换器中的断点甚至都不会命中。
我可以通过将属性设置为object
,然后在使用它的地方强制转换为Dictionary
,使其工作,但这是一个丑陋的解决方案。
是否有一种方法可以强制JsonSerializer.DeserializeAsync<T>(myJson)
只使用我的转换器,而不必试图自己变得聪明?
(我正在.NET Core 3中使用Microsoft的System.Text.Json)
答案 0 :(得分:0)
好的,所以这可能是System.Text.Json
中的错误。
这是我目前正在为其他需要解决方案的人使用的解决方法。
首先,我使用[JsonPropertyName]
和[JsonIgnore]
设置了两个用于反序列化的属性:
[JsonPropertyName("parameters"), JsonConverter(typeof(QueryStringToDictionaryJsonConverter))]
public object ParametersObject { get; set; }
[JsonIgnore]
public Dictionary<string, string> Parameters => ParametersObject as Dictionary<string, string>;
然后在JsonConverter
中,我允许object
作为类型:
public override bool CanConvert(Type typeToConvert) {
if (typeToConvert == typeof(object)) return true;
return base.CanConvert(typeToConvert);
}
我的反序列化类的消费者仅使用Parameters
属性,如果修复了该错误,并且当我将该类更改回所需的状态时,该属性将继续正常工作。
答案 1 :(得分:0)
我将创建一个包装器,并为该包装器创建一个转换器。
[JsonConverter( typeof( QueryStringDictionaryConverter ) )]
class QueryStringDictionary : Dictionary<string,string> { }
class QueryStringDictionaryConverter : JsonConverter<QueryStringDictionary>
{
...
}
class MyClass
{
public QueryStringDictionary Parameters { get; set; }
}
或者,您可以使用JsonSerializerOptions
class MyOtherClass
{
public Dictionary<string,string> Parameters { get; set; }
}
MyOtherClass Deserialize( string json )
{
var options = new JsonSerializerOptions
{
Converters = { new QueryStringToDictionaryJsonConverter() }
};
return JsonSerializer.Deserialize<MyOtherClass>( json, options );
}
此方法的潜在问题是,转换器可能会在所有Dictionary<string,string>
属性上使用,这可能是不希望的。对于原始问题中的简单示例,它会很好地工作。