我的问题是,我需要将Newtonsoft.Json.Deserializer
反序列化为包含接口类型对象的类型,因此需要指示Json.NET如何转换该接口类型,但不能直接控制JSON。反序列化由框架代码间接处理,即由HttpContent.ReadAsAsync处理。
我如何指定从接口类型到具体类型的转换,而不能直接将转换器添加到JsonSerializer.Converters
?如果我在接口定义上使用[JsonConverter]
属性,转换器也会被调用来实现接口(即我要转换成的具体类型)。
下面的代码显示了一个C#控制台程序,该程序试图将相同的JSON反序列化为首先是Parent2
类,然后是Parent1
类,指示Json.NET通过JsonConverterAttribute
将IChild1
接口类型转换为Child1
具体类型。对Parent2
的反序列化之所以起作用,是因为我将ChildConverter
直接添加到serializer.Converters
,而反序列化到Parent1
会导致堆栈溢出异常,这是因为即使对于Child1
类型也会调用ChildConverter.Deserialize
。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
namespace TestConsole
{
[JsonConverter(typeof(ChildConverter))]
interface IChild1
{
string Name { get; set; }
}
class Child1 : IChild1
{
public string Name { get; set; }
}
class Parent1
{
public IEnumerable<IChild1> Children { get; set; }
}
interface IChild2
{
string Name { get; set; }
}
class Child2 : IChild2
{
public string Name { get; set; }
}
class Parent2
{
public IEnumerable<IChild2> Children { get; set; }
}
class ChildConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IChild1) || objectType == typeof(IChild2);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(IChild1))
return serializer.Deserialize<Child1>(reader);
return serializer.Deserialize<Child2>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
var json = "{'Children': [{'Name': 'Child1'}, {'Name': 'Child2'}]}";
var serializer = new JsonSerializer();
serializer.Converters.Add(new ChildConverter());
var obj = serializer.Deserialize(new StringReader(json), typeof(Parent2));
serializer = new JsonSerializer();
obj = serializer.Deserialize(new StringReader(json), typeof(Parent1));
}
}
}
发布于 2012-08-31 10:39:04
我找到了一个解决我的特殊问题的方法,那就是调用HttpContent.ReadAsAsync并让它反序列化一个JSON响应。虽然我的解决方案不能解决在不访问序列化程序的情况下配置Json.NET类型转换的一般问题,但它确实解决了我的特定问题。我发现HttpContent.ReadAsync<T>
接受一个用于反序列化响应的IEnumerable<MediaTypeFormatter>
。这里可以传递一个JsonMediaTypeFormatter
,它已经使用您选择的JsonConverter
(在我的示例中是ChildConverter
)进行了配置。
var formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings.Converters.Add(new ChildConverter());
var obj = await resp.Content.ReadAsAsync<T>(new MediaTypeFormatter[] {formatter});
https://stackoverflow.com/questions/12211161
复制相似问题