Angular 7中使用protobuf-net生成的含bcl.proto的Proto文件反序列化疑问
Great question! This is a common pitfall when mixing protobuf-net (optimized for .NET ecosystem compatibility) with front-end tooling that expects standard Protocol Buffers definitions.
Will this cause issues in Angular?
Yes, absolutely. The protobuf-net/bcl.proto imports and types like .bcl.Guid/.bcl.Decimal are protobuf-net-specific extensions built to map .NET's unique types to Protocol Buffers. Frontend tools like protobuf.js or ts-proto (which you’d use in Angular 7) don’t recognize these custom types, so they’ll either fail to compile the proto file or throw deserialization errors at runtime.
Simplest solution (no manual proto writing required)
The best fit for your scenario—lots of classes, no desire to hand-write proto files—is to configure protobuf-net to generate standard Protocol Buffers-compatible definitions instead of relying on its .NET-specific extensions. You can do this with global type surrogates in your .NET project, which map .NET types like Guid and decimal to standard proto equivalents.
Here’s how to implement it:
Add global type configuration in your .NET project
In your application startup code (e.g.,Startup.csorProgram.cs), configure theRuntimeTypeModelto map .NET types to standard proto types:using ProtoBuf.Meta; // Run this once at app startup var typeModel = RuntimeTypeModel.Default; // Map Guid to standard string (easy for frontend to parse) typeModel.Add(typeof(Guid), false) .SetSurrogate(typeof(string)); // Map decimal to either: // - double: if precision isn't critical (e.g., non-currency values) typeModel.Add(typeof(decimal), false) .SetSurrogate(typeof(double)); // OR // - string: if you need full precision (e.g., currency, financial data) // typeModel.Add(typeof(decimal), false) // .SetSurrogate(typeof(string));Regenerate your proto files
After applying this configuration, runSerializer.GetProto<AssemblyComponentDetailsModel>()again. The output will now use standard proto types with no dependencies onbcl.proto:syntax = "proto2"; package MyProject.Models; message AssemblyComponentDetailsModel { optional string ID = 1 [default = "00000000-0000-0000-0000-000000000000"]; optional string AssemblyName = 2; optional string ReferenceNumber = 3; optional string TypeID = 4 [default = "00000000-0000-0000-0000-000000000000"]; optional string CategoryID = 5 [default = "00000000-0000-0000-0000-000000000000"]; optional string Symbol = 6; repeated ComponentDetailsModel ComponentDetails = 7; optional double MsrpTotal = 8 [default = 0]; }Use the new proto in Angular
This standard proto file will work seamlessly with your existing frontend workflow (usingprotobuf.jsorts-proto). Frontend code can directly parse string Guids into JavaScript objects, and handle doubles/strings for decimal values as needed.
Additional tips
- For decimal values requiring full precision (like currency), use the string surrogate. You can use a library like
js-big-decimalin Angular to parse these strings back into high-precision numbers. - This global configuration applies to all your classes—no need to modify each model individually, which is perfect for your large codebase.
- Test end-to-end serialization/deserialization to ensure data consistency between .NET and Angular (e.g., verify Guid strings are parsed correctly, decimal values retain precision).
内容的提问来源于stack exchange,提问作者Dominick

