使用AddXmlDataContractSerializer序列化子资源失败求助
解决DataContractSerializer XML序列化已知类型错误
问题原因
这个XML序列化错误,是因为DataContractSerializer(AddXmlDataContractSerializerFormatters使用的序列化器)无法识别接口ICollection<BDto>对应的实际实现类型List<BDto>。你在ADto里定义的是接口,但接口不能直接被序列化,实际返回的是List实例,而序列化器没有提前知晓这个具体类型,所以抛出了“类型未预期”的错误。JSON序列化正常是因为JSON序列化器默认支持这种接口与具体实现的映射,不需要额外配置。
三种解决办法
方法一:给ADto添加KnownType特性
在ADto类上标注[KnownType]特性,明确告诉序列化器可能用到的具体实现类型:[KnownType(typeof(List<BDto>))] class ADto { public string Name { get; set; } public ICollection<BDto> BDtos { get; set; } = null; }方法二:在XML序列化配置中添加全局已知类型
在Program.cs(或Startup.cs)配置控制器时,给XML序列化器添加已知类型:services.AddControllers() .AddXmlDataContractSerializerFormatters(options => { // 全局添加所有需要的已知类型 options.KnownTypes.Add(typeof(List<BDto>)); });也可以针对特定类型单独配置序列化器:
services.AddControllers() .AddXmlDataContractSerializerFormatters(options => { options.SetSerializer<ADto>(new DataContractSerializer(typeof(ADto), new[] { typeof(List<BDto>) })); });方法三:直接替换接口为具体实现类
如果不需要保持ICollection<BDto>的接口抽象,直接把属性类型改成List<BDto>,序列化器就能直接识别:class ADto { public string Name { get; set; } public List<BDto> BDtos { get; set; } = null; }
选择建议
如果需要保留接口的灵活性(比如后续可能换其他ICollection实现),选前两种方法;如果对类型灵活性要求不高,第三种方法最简单直接,不需要额外配置。
内容的提问来源于stack exchange,提问作者Sumit Khunger
相关产品推荐
相关产品推荐

