Xamarin Forms调用JsonConvert.SerializeObject序列化无报错崩溃如何解决
问题根因
你遇到的崩溃是典型的无限递归序列化导致的堆栈溢出异常,这类异常属于.NET运行时不可恢复错误,普通的try-catch无法捕获,所以你看不到常规错误信息。
因为Booking和Student是多对多关系,你设置了ReferenceLoopHandling.Serialize,序列化时会陷入Booking→Students→Student→Bookings→Booking的无限递归,最终堆栈占满直接崩溃。
第一步:获取完整错误信息
要捕获这类崩溃日志,你可以用两种方式:
- 查看Android Logcat日志
打开Visual Studio的设备日志(Logcat),过滤你的应用包名,崩溃时会输出完整的堆栈溢出错误栈,可直接定位到序列化递归的问题。 - 注册全局未处理异常捕获
在App.xaml.cs的构造函数中添加三个全局异常监听,就能捕获所有未处理的错误:public App() { InitializeComponent(); // 捕获UI线程未处理异常 Xamarin.Forms.Device.BeginInvokeOnMainThread(() => { AppDomain.CurrentDomain.UnhandledException += (s, e) => { var ex = (Exception)e.ExceptionObject; // 这里输出日志或保存到本地 System.Diagnostics.Debug.WriteLine($"Unhandled Exception: {ex}"); }; }); // 捕获异步任务未处理异常 TaskScheduler.UnobservedTaskException += (s, e) => { System.Diagnostics.Debug.WriteLine($"Unobserved Task Exception: {e.Exception}"); e.SetObserved(); }; // 捕获Android平台原生异常 Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (s, e) => { System.Diagnostics.Debug.WriteLine($"Android Unhandled Exception: {e.Exception}"); e.Handled = true; }; MainPage = new AppShell(); }
第二步:解决循环引用序列化问题(无需JsonIgnore,保留学生数据)
你之前对ReferenceLoopHandling.Ignore的理解有误,这个配置不会丢失你需要的Students数据,它的作用是:当序列化遇到已经遍历过的对象时,仅跳过当前循环分支的序列化,不会删除已输出的属性。
你的场景下,只会跳过Student对象内的Bookings集合序列化,你需要的Booking下的Students完整数据会完全保留:
var serializerSettings = new JsonSerializerSettings { // 替换Serialize为Ignore即可 ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore, // 可选:如果服务端也用Newtonsoft,还可以开启引用保留,完整保留对象关系 // PreserveReferencesHandling = PreserveReferencesHandling.Objects };
额外代码问题修复
你当前的AddToBooking方法存在逻辑错误:你是先序列化booking对象,再给booking.CreatedBy赋值,最终提交到接口的JSON里不会包含CreatedBy字段,需要调整顺序:
// 先赋值,再序列化 booking.CreatedBy = db.GetActiveUser(); string json = JsonConvert.SerializeObject(booking,Formatting.Indented, serializerSettings);
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

