Xamarin.Forms Android平台SOAP反序列化失败问题求助
解决Xamarin.Forms中Android端派生类反序列化失败的问题
问题本质
这不是Xamarin.Forms的已知Bug,核心原因是不同平台下序列化器的类型识别配置不一致:
- UWP平台默认使用的序列化器(如DataContractSerializer)会自动处理已知派生类型;
- Android端使用的序列化器(如Newtonsoft.Json、System.Text.Json或WCF客户端的序列化实现)需要显式配置派生类的类型映射,否则只会反序列化基类属性,派生类属性会被置为默认值(0或null)。
具体解决方法
根据你使用的序列化框架,选择对应方案:
1. 使用Newtonsoft.Json的场景
如果项目依赖Newtonsoft.Json,有两种配置方式:
- 方式一:通过特性标记
在抽象基类TestBase上添加类型识别特性,指定区分派生类的字段名,并标记所有派生类:using Newtonsoft.Json; using Newtonsoft.Json.Converters; [JsonConverter(typeof(JsonSubtypes), "Type")] // "Type"是服务端返回的区分派生类的字段名 [JsonSubtypes.KnownSubType(typeof(TestClass1), "TestClass1")] [JsonSubtypes.KnownSubType(typeof(TestClass2), "TestClass2")] public abstract class TestBase { // 基类属性定义 public string Type { get; set; } // 服务端返回的用来区分类型的字段 } public class TestClass1 : TestBase { // TestClass1专属属性 } public class TestClass2 : TestBase { // TestClass2专属属性 } - 方式二:通过序列化配置
反序列化时指定TypeNameHandling,让序列化器识别类型信息(需服务端返回的JSON包含$type字段):var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, NullValueHandling = NullValueHandling.Ignore }; var responseObj = JsonConvert.DeserializeObject<TestBase>(responseContent, settings);
2. 使用System.Text.Json的场景
针对较新的Xamarin项目(使用.NET 6+),配置JsonSerializerOptions添加派生类型映射:
using System.Text.Json; using System.Text.Json.Serialization; var options = new JsonSerializerOptions(); // 添加派生类型与标识值的映射,"Type1"对应服务端返回的区分字段值 options.AddDerivedType<TestBase, TestClass1>("Type1"); options.AddDerivedType<TestBase, TestClass2>("Type2"); var responseObj = JsonSerializer.Deserialize<TestBase>(responseContent, options);
或者创建自定义转换器处理类型识别逻辑,适配服务端的返回格式。
3. 基于WCF客户端的场景
如果是Visual Studio生成的WCF客户端代码,需要在基类上添加[KnownType]特性,让DataContractSerializer识别派生类:
using System.Runtime.Serialization; [DataContract] [KnownType(typeof(TestClass1))] [KnownType(typeof(TestClass2))] public abstract class TestBase { [DataMember] // 基类属性定义 }
检查自动生成的客户端代码,如果未自动添加这些特性,手动补充到TestBase类上即可。
额外注意事项
- 服务端类型标识:确保服务端返回的响应中包含足够的类型区分信息(如XML的
xsi:type属性、JSON的类型字段),否则客户端无法正确识别派生类。 - Android混淆配置:如果开启了代码混淆,需在ProGuard配置文件中保留序列化相关类,避免类型信息被混淆:
-keep class YourNamespace.TestBase { *; } -keep class YourNamespace.TestClass1 { *; } -keep class YourNamespace.TestClass2 { *; }
内容的提问来源于stack exchange,提问作者Bernd Morgeneyer
相关产品推荐
相关产品推荐

