临时说明:这不是上述帖子的重复
假设我有一个像这样的服务器端类结构。
public class Test
{
// this can be any kind of "Tag"
public object Data { get; set; }
}
public class Other
{
public string Test { get; set; }
}
现在这样的字符串就是来自客户端。
{"Data": [{$type: "MyProject.Other, MyProject", "Test": "Test"}] }
当我尝试将其反序列化为Test
实例时,我得到的结果是Tag
属性为JToken
而不是某种集合,例如{{1} }或ArrayList
。
我理解List<object>
无法反序列化为强类型列表,但我希望它尊重它至少是一个列表。
这是我当前的反序列化代码。
Json.NET
我知道如果我序列化这样的结构,那么默认情况下我会在JSON字符串中获得var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
};
var str = "{\"Data\": [{\"$type\": \"MyProject.Other, MyProject\", \"Test\": \"Test\"}] }";
var test = JsonConvert.Deserialize<Test>(str, settings);
// this first assertion fails
(test.Data is IList).ShouldBeTrue();
(((IList)test.Data)[0] is Other).ShouldBeTrue();
结构而不是纯数组文字,这确实会正确地反序列化。但是,客户端正在发送一个纯数组文字,所以我应该能够以某种方式处理它。
答案 0 :(得分:1)
我成功地组建了一个JsonConverter
来处理这类无类型列表。当目标类型为object
时,转换器适用。然后,如果当前令牌类型是数组start([
),它将强制反序列化为List<object>
。在任何其他情况下,它将回退到正常反序列化。
这是第一个通过我最重要的单元测试的版本,但由于我不是Json.NET
专家,它可能会意外地破坏一些事情。如果有人看到我没有看到的任何内容,请发表评论。
public class UntypedListJsonConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanRead => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartArray)
{
return serializer.Deserialize(reader);
}
return serializer.Deserialize<List<object>>(reader);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(object);
}
}
用法示例:
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto,
Converters = new[] { new UntypedListJsonConverter() }
};
var str = "{\"Data\": [{\"$type\": \"MyProject.Other, MyProject\", \"Test\": \"Test\"}] }";
var test = JsonConvert.Deserialize<Test>(str, settings);
// now these assertions pass
(test.Data is IList).ShouldBeTrue();
(((IList)test.Data)[0] is Other).ShouldBeTrue();
答案 1 :(得分:0)
试试这个:
public class Test
{
public Dictionary<string, List<Other>> Data { get; } = new Dictionary<string, List<Other>>();
}
您需要设置要从json数据填充的类,以便与json结构紧密匹配。从它的外观来看,json看起来是一个字典,其中键是字符串,值是Other
个对象的数组。