Xamarin Forms中DataAnnotations在Live Player崩溃的处理方案咨询
解决Xamarin Live Player中DataAnnotations引发的崩溃问题
你遇到的这个情况确实挺头疼的——既要复用数据模型层带DataAnnotations的类来反序列化JSON,又被Xamarin Live Player的已知Bug卡着崩溃。这里给你几个实用的解决思路,不用维护多版本模型就能搞定:
思路一:用条件编译让Live Player自动跳过DataAnnotations
我们可以通过编译指令,让代码在Live Player环境下不加载DataAnnotations,其他环境正常使用:
- 给数据模型里的DataAnnotations加上条件编译标记:
using System.ComponentModel.DataAnnotations; public class JobsList { #if !LIVE_PLAYER [Required] [StringLength(50)] #endif public string JobId { get; set; } #if !LIVE_PLAYER [Display(Name = "Job Name")] #endif public string JobName { get; set; } // 其他属性按需添加 }
- 给Live Player的调试配置加编译符号:
右键你的Xamarin Forms项目 → 「属性」→ 「生成」→ 找到「条件编译符号」,在对应Live Player使用的调试配置里添加LIVE_PLAYER。
这样一来,用Live Player运行时,这些注解会被忽略,不会触发崩溃;在模拟器或真机上调试时,注解正常生效,完全不影响JSON反序列化和验证逻辑。
思路二:用分部类拆分模型和注解
如果不想改动原有模型的代码,可以把DataAnnotations单独放到一个分部类文件里,同样用编译符号控制是否编译:
- 原有数据模型保持不变(不带任何注解):
// 数据模型层的JobsList.cs public partial class JobsList { public string JobId { get; set; } public string JobName { get; set; } // 其他属性 }
- 新建一个注解分部类文件(比如
JobsList.Annotations.cs):
#if !LIVE_PLAYER using System.ComponentModel.DataAnnotations; public partial class JobsList { [Required] [StringLength(50)] public string JobId { get; set; } [Display(Name = "Job Name")] public string JobName { get; set; } } #endif
同样给Live Player的配置加上LIVE_PLAYER编译符号,这个注解文件在Live Player运行时就不会被编译,完美避开Bug。
思路三:暂时换用模拟器/真机调试
如果觉得编译配置有点繁琐,也可以暂时放弃Xamarin Live Player,改用模拟器或者真实设备调试。毕竟Live Player只是快速预览工具,正式开发调试用模拟器或真机不仅更稳定,也不会受这个DataAnnotations Bug的影响。
先回顾下你的现有代码结构,确保解决方案能适配你的场景:
你的Web客户端DLL代码:
public class xxxWc : IHttpService { readonly IJsonConverter jsonConverter; public xxxWc() {} public FuelWc(IJsonConverter jsonConverter) { this.jsonConverter = jsonConverter; } public async Task<T> Get<T>(string url) { using (var client = new System.Net.Http.HttpClient()) { var response = await client.GetAsync(url); var json = await response.Content.ReadAsStringAsync(); return jsonConverter.Deserialize<T>(json); } } }
API客户端代码:
public class xxxApiClient : IApi { readonly string url = "http://localhost:81/api "; readonly IHttpService httpService; public xxxApiClient(IHttpService httpService) { this.httpService = httpService; } public Task<List<JobsList>> GetJobs() => httpService.Get<List<JobsList>>($"{url}JobsLists"); }
视图代码:
using xxxxx; using xxxxx.Interface; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace xxxxxCallMangmentApp.Views { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class JobsPage : ContentPage { IApi api; public JobsPage() { InitializeComponent (); SetItemSource(); } private async void SetItemSource() { JobListingsListView.ItemsSource = await api.GetJobs(); } } }
内容的提问来源于stack exchange,提问作者David B
相关产品推荐
相关产品推荐

