Xamarin.Forms Android中Json.Net序列化JMessage丢失Type属性问题求助
这问题我之前在Xamarin.Android项目里踩过类似的坑,大概率是Json.Net在Android平台对System.Type类型的序列化处理差异,或者是Xamarin.Android的链接器优化裁剪了相关元数据导致的。结合你的情况,给你几个可行的排查和解决方向:
1. 改用字符串存储Type信息(最稳妥的方案)
Json.Net直接序列化Type类型在Android的AOT编译环境下容易出问题,建议把Type转换成它的AssemblyQualifiedName字符串来存储,彻底避开平台差异:
修改你的JMessage类如下:
public class JMessage { [JsonIgnore] // 忽略直接序列化Type属性 public Type Type { get; set; } // 序列化时存储Type的完整名称 [JsonProperty("Type")] public string TypeName { get => Type?.AssemblyQualifiedName; set => Type = value != null ? Type.GetType(value) : null; } public JToken Value { get; set; } public static JMessage FromValue<T>(T value) { return new JMessage { Type = typeof(T), Value = JToken.FromObject(value) }; } public static string Serialize(JMessage message) { return JToken.FromObject(message).ToString(); } public static JMessage Deserialize(string data) { return JToken.Parse(data).ToObject<JMessage>(); } }
这样序列化后的JSON会包含Type字段的字符串值,反序列化时也能正确还原成Type对象,UWP和iOS的行为不受影响,Android的问题也能解决。
2. 检查Xamarin.Android链接器设置
如果你的应用是在Release模式下出现问题,很大可能是链接器把Type相关的元数据给裁剪了。可以先临时把链接器行为改成**“不链接”**(在Android项目属性 -> Android选项 -> 链接器)测试:
- 如果问题消失,说明是链接器的锅。这时不要一直用“不链接”(会增大包体积),而是创建一个链接器配置文件
Linker.xml,添加以下内容:
<?xml version="1.0" encoding="utf-8" ?> <linker> <!-- 替换成你的项目程序集名称 --> <assembly fullname="YourAppAssembly"> <type fullname="JMessage" preserve="all" /> </assembly> <!-- 如果你的Value里涉及到其他需要保留的类型,也可以在这里添加 --> </linker>
把这个文件设置为Android项目的嵌入的资源,这样链接器就不会裁剪JMessage类的相关元数据了。
3. 升级/回退Json.Net版本
有可能是你当前使用的Newtonsoft.Json版本和Xamarin.Android的版本不兼容。尝试升级到最新稳定版的Newtonsoft.Json,或者回退到之前能正常工作的版本,看看问题是否消失。
4. 手动控制序列化逻辑
如果不想修改JMessage类结构,可以手动在序列化/反序列化时处理Type属性:
public static string Serialize(JMessage message) { var jObj = new JObject(); // 手动添加Type的完整名称 jObj["Type"] = message.Type?.AssemblyQualifiedName; jObj["Value"] = message.Value; return jObj.ToString(); } public static JMessage Deserialize(string data) { var jObj = JToken.Parse(data); return new JMessage { Type = Type.GetType(jObj["Type"]?.ToString()), Value = jObj["Value"] }; }
这种方式完全绕过Json.Net自动序列化Type的逻辑,强制用字符串存储类型信息,也能解决平台差异问题。
内容的提问来源于stack exchange,提问作者octillerysnacker

