我正在尝试移动一些代码来使用ASP.NET MVC Web API生成的Json数据,而不是SOAP Xml。
我在序列化和反序列化类型的属性时遇到了一个问题:
IEnumerable<ISomeInterface>.
下面是一个简单的例子:
public interface ISample{
int SampleId { get; set; }
}
public class Sample : ISample{
public int SampleId { get; set; }
}
public class SampleGroup{
public int GroupId { get; set; }
public IEnumerable<ISample> Samples { get; set; }
}
}
我可以使用以下命令轻松序列化SampleGroup实例:
var sz = JsonConvert.SerializeObject( sampleGroupInstance );
然而,相应的反序列化失败:
JsonConvert.DeserializeObject<SampleGroup>( sz );
使用此异常消息:
“无法创建类型JsonSerializationExample.ISample的实例。类型是接口或抽象类,不能是即时的。”
如果我派生一个JsonConverter,我可以像下面这样装饰我的属性:
[JsonConverter( typeof (SamplesJsonConverter) )]
public IEnumerable<ISample> Samples { get; set; }
下面是JsonConverter:
public class SamplesJsonConverter : JsonConverter{
public override bool CanConvert( Type objectType ){
return ( objectType == typeof (IEnumerable<ISample>) );
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer ){
var jA = JArray.Load( reader );
return jA.Select( jl => serializer.Deserialize<Sample>( new JTokenReader( jl ) ) ).Cast<ISample>( ).ToList( );
}
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer ){
... What works here?
}
}
这个转换器解决了反序列化问题,但是我不知道如何对WriteJson方法进行编码以使序列化再次工作。
有人能帮上忙吗?
首先,这是解决问题的“正确”方法吗?
发布于 2014-01-14 17:57:14
它非常简单,由json.net提供开箱即用的支持,您只需在序列化和反序列化时使用以下JsonSettings:
JsonConvert.SerializeObject(graph,Formatting.None, new JsonSerializerSettings()
{
TypeNameHandling =TypeNameHandling.Objects,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
对于反序列化,请使用以下代码:
JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bData),type,
new JsonSerializerSettings(){TypeNameHandling = TypeNameHandling.Objects}
);
只需注意JsonSerializerSettings对象初始化器,这对您来说很重要。
发布于 2013-07-16 23:22:09
非常好的解决方案,谢谢!我采用了AndyDBell的问题和Cuong Le的答案,构建了一个具有两个不同接口实现的示例:
public interface ISample
{
int SampleId { get; set; }
}
public class Sample1 : ISample
{
public int SampleId { get; set; }
public Sample1() { }
}
public class Sample2 : ISample
{
public int SampleId { get; set; }
public String SampleName { get; set; }
public Sample2() { }
}
public class SampleGroup
{
public int GroupId { get; set; }
public IEnumerable<ISample> Samples { get; set; }
}
class Program
{
static void Main(string[] args)
{
//Sample1 instance
var sz = "{\"GroupId\":1,\"Samples\":[{\"SampleId\":1},{\"SampleId\":2}]}";
var j = JsonConvert.DeserializeObject<SampleGroup>(sz, new SampleConverter<Sample1>());
foreach (var item in j.Samples)
{
Console.WriteLine("id:{0}", item.SampleId);
}
//Sample2 instance
var sz2 = "{\"GroupId\":1,\"Samples\":[{\"SampleId\":1, \"SampleName\":\"Test1\"},{\"SampleId\":2, \"SampleName\":\"Test2\"}]}";
var j2 = JsonConvert.DeserializeObject<SampleGroup>(sz2, new SampleConverter<Sample2>());
//Print to show that the unboxing to Sample2 preserved the SampleName's values
foreach (var item in j2.Samples)
{
Console.WriteLine("id:{0} name:{1}", item.SampleId, (item as Sample2).SampleName);
}
Console.ReadKey();
}
}
和SampleConverter的通用版本:
public class SampleConverter<T> : CustomCreationConverter<ISample> where T: new ()
{
public override ISample Create(Type objectType)
{
return ((ISample)new T());
}
}
发布于 2012-08-01 22:10:36
在我的项目中,这段代码总是作为默认的序列化程序工作,它序列化指定的值,就像没有特殊的转换器一样:
serializer.Serialize(writer, value);
https://stackoverflow.com/questions/11754633
复制相似问题