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
相关产品推荐
相关产品推荐

