UWP应用使用Protobuf生成类时出现XAML WMC9999编译错误如何解决
问题1 错误消除方案
该错误是XAML编译器扫描公共属性的类型时,无法识别Protobuf原生的RepeatedField<T>集合类型导致,RepeatedField<T>是Protobuf为了序列化效率设计的标准集合类型,无法通过修改protoc编译逻辑取消生成,可通过以下方案解决:
- 方案1:修改属性访问修饰符(最简单,无需额外代码)
若无需在XAML中直接绑定TestClasses属性,将属性的访问修饰符从public改为internal,XAML编译器默认仅扫描public类型生成类型信息,可直接规避检查:internal List<TestClass> TestClasses { get; } = new List<TestClass>(); - 方案2:添加忽略绑定特性
若需要保留属性的public访问权限,给属性添加[Bindable(false)]特性,告知XAML编译器无需为该类型生成绑定信息:[System.ComponentModel.Bindable(false)] public List<TestClass> TestClasses { get; } = new List<TestClass>(); - 方案3:增加DTO映射层(推荐,符合架构规范)
不要直接把Protobuf生成的传输类作为UI层的数据源,单独编写UI层使用的业务模型类,将RepeatedField<T>手动转换为标准的List<T>/ObservableCollection<T>后再给UI使用,从根源规避XAML类型检查问题。 - 方案4:修改项目配置禁用XAML类型生成
若项目整体不需要XAML原生绑定的类型反射能力,可在项目的.csproj文件中添加配置,全局禁用XAML类型信息生成:<PropertyGroup> <DisableXamlTypeInfoGeneration>True</DisableXamlTypeInfoGeneration> </PropertyGroup>
问题2 UWP使用Protobuf+gRPC的最佳实践
- 层级分离
严格区分传输层和UI层:Protobuf生成的类仅作为客户端和服务端通信的传输对象使用,禁止直接暴露给UI层做绑定。UI层单独编写ViewModel/Model,通过手动映射或者AutoMapper等工具完成传输对象到业务模型的转换,RepeatedField<T>统一转换为标准集合类型后再交给UI层使用。
- 层级分离
- gRPC配置适配UWP
- 在Package.appxmanifest中开启对应网络权限:访问公网服务开启「Internet(客户端)」权限,访问本地局域网服务额外开启「专用网络(客户端和服务器)」权限。
- UWP对HTTP/2的完善支持从Windows 10 1903版本开始,若需要兼容更低版本系统,改用gRPC-Web作为传输协议。
- 编译配置优化
不要手动调用protoc生成C#类,直接在项目中配置Grpc.Tools的自动生成逻辑,将proto文件的生成操作设置为Protobuf Compiler,示例.csproj配置:
<ItemGroup> <Protobuf Include="Protos\*.proto" GrpcServices="Client" /> </ItemGroup> <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.17.3" /> <PackageReference Include="Grpc.Tools" Version="2.40.0" PrivateAssets="All" /> <PackageReference Include="Grpc.Net.Client" Version="2.40.0" /> </ItemGroup>- 编译配置优化
- 类型检查规避
所有Protobuf生成的类统一放在单独的传输层命名空间下,所有传输类相关的公共属性要么添加[Bindable(false)]特性,要么设置为internal访问权限,避免XAML编译器扫描到传输层类型触发检查。
- 类型检查规避
内容的提问来源于stack exchange,提问作者richej
相关产品推荐
相关产品推荐

