You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms Android中Json.Net序列化JMessage丢失Type属性问题求助

解决Xamarin.Forms Android下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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:35:26