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

Xamarin Forms反序列化Type类型遇CultureNotFoundException问题求助

问题解决:Xamarin Forms中FlyoutItemPage反序列化CultureNotFoundException错误

问题原因

你遇到的错误是因为Json.NET默认序列化Type类型时,会输出包含Culture、PublicKeyToken的完整程序集限定名,但反序列化时,解析器错误地将neutral, PublicKeyToken=null部分识别为Culture名称,从而抛出CultureNotFoundException。此外,你的FlyoutItemPage类缺少无参构造函数,这也是反序列化可能失败的隐性问题。

解决方案一:修改类结构,存储类型名称字符串

这种方法简单直接,通过存储页面类型的字符串名称替代直接序列化Type对象,避免解析错误。

1. 修改FlyoutItemPage类

添加无参构造函数(反序列化必需),新增用于序列化的类型名称属性,标记原TargetPage属性不参与序列化:

public class FlyoutItemPage
{
    // 无参构造函数,反序列化必备
    public FlyoutItemPage() { }

    public FlyoutItemPage(string title, Type targetPage)
    { 
        Title = title;
        TargetPage = targetPage;
        // 存储类型的完整程序集名称
        TargetPageName = targetPage.AssemblyQualifiedName;
    }

    public string Title { get; set; }

    // 标记该属性不参与JSON序列化/反序列化
    [JsonIgnore]
    public Type TargetPage { get; set; }  

    // 用于序列化的类型名称字符串
    public string TargetPageName { get; set; }
}

2. 反序列化时恢复Type对象

在OnAppearing方法中,反序列化后手动将字符串转换为Type:

protected override void OnAppearing()
{
    base.OnAppearing();

    try
    {
        var json = Preferences.Get("favorites", "");
        if (string.IsNullOrEmpty(json)) 
        {
            return;
        }
        
        var flyoutItemPages = JsonConvert.DeserializeObject<ObservableCollection<FlyoutItemPage>>(json);
        
        // 遍历集合,将类型名称字符串转换为Type对象
        foreach (var item in flyoutItemPages)
        {
            if (!string.IsNullOrEmpty(item.TargetPageName))
            {
                item.TargetPage = Type.GetType(item.TargetPageName);
            }
        }
      
        // 此处可将flyoutItemPages绑定到ListView的ItemsSource
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

序列化逻辑无需修改,原代码可正常运行。

解决方案二:自定义JsonConverter处理Type类型

如果不想修改类结构,可以通过自定义转换器来处理Type的序列化与反序列化逻辑。

1. 创建TypeConverter类

public class TypeConverter : JsonConverter<Type>
{
    public override Type ReadJson(JsonReader reader, Type objectType, Type existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var typeName = reader.Value as string;
        if (string.IsNullOrEmpty(typeName))
            return null;
        
        // 直接通过类型名称获取Type对象,避开默认解析的Culture问题
        return Type.GetType(typeName);
    }

    public override void WriteJson(JsonWriter writer, Type value, JsonSerializer serializer)
    {
        writer.WriteValue(value.AssemblyQualifiedName);
    }
}

2. 使用转换器序列化/反序列化

序列化时:

var json = JsonConvert.SerializeObject(flyoutItemPages, new TypeConverter());
Preferences.Set("favorites", json);

反序列化时:

var flyoutItemPages = JsonConvert.DeserializeObject<ObservableCollection<FlyoutItemPage>>(json, new TypeConverter());

同时记得给FlyoutItemPage添加无参构造函数:

public FlyoutItemPage() { }

内容的提问来源于stack exchange,提问作者Mert Altiparmak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:50:00