Protobuf naar C# Converter
Plak een .proto-schema. Krijg C#-classes met auto-properties — direct in je project te droppen, geen protoc-plugin nodig.
Input (.proto-schema)
Output (C#)
Wat deze tool doet
Je hebt een Protocol Buffers-schema en een C#-service of -client die de bijhorende DTOs nodig heeft. De officiële weg is protoc met de C#-plugin installeren (of Grpc.Tools in je .csproj hangen) en MSBuild tijdens de build de partial classes laten genereren. Dat werkt, maar het is overdreven als je gewoon het schema wil lezen, types wil schetsen of een message in een Razor-pagina of eenmalige integratie wil plakken. Deze converter doet dezelfde soort klus — plakken, kopiëren, in Types.cs droppen.
De type-mapping is van het saaie-maar-correcte soort. string blijft string (met = ""-initializer zodat projecten met nullable references niet zeuren). bool, int32, int64, uint32, uint64, float, double mappen naar respectievelijk bool, int, long, uint, ulong, float, double. bytes wordt byte[]. repeated T wordt List<T>, map<K, V> wordt Dictionary<K, V>, en bekende wrappers zoals google.protobuf.Timestamp komen eruit als string (de proto3-JSON-encoding voor timestamps is RFC 3339, op wire-niveau gewoon een string — zie de proto3 JSON-spec voor de details).
Veldnamen krijgen de standaard PascalCase-behandeling — order_id → OrderId, shipping_address → ShippingAddress — net als wat de officiële C# protobuf-reference oplevert. Enum-waarden raken hun SCREAMING_SNAKE-prefix kwijt als het schema de conventie volgt om elke waarde te prefixen met de enum-naam (dus ORDER_STATUS_PENDING in enum OrderStatus wordt OrderStatus.Pending). De output-classes zijn plat — elke geneste message wordt naar het top-level getild, zodat je ze kunt opsplitsen of herschikken zonder scopes uit elkaar te trekken. De conversie gebeurt volledig in je browser; niets van het schema wordt geüpload.
Zo gebruik je het
Drie stappen. De output is klaar om te compileren — plak hem in een <code>Types.cs</code>-bestand in je project.
Plak je .proto-schema
Drop het schema in de linker editor. syntax = "proto3"; bovenaan is optioneel. De parser snapt geneste message-blokken, enum-declaraties, oneof, map<K, V>, veldopties en de gebruikelijke package/import/option-directives. Imports worden herkend maar overgeslagen, dus plak geïmporteerde types inline mee als je schema ervan afhangt.
Veldnaam-conversie gaat automatisch: customer_name in .proto wordt CustomerName in C#. Class- en enum-namen blijven zoals ze zijn (per conventie al PascalCase).
Lees de output
Rechts: public class-declaraties met { get; set; }-auto-properties voor elke message, plus public enum-declaraties voor elke enum. Er wordt een using System.Collections.Generic;-regel toegevoegd als het schema repeated- of map-velden gebruikt (zodat List en Dictionary resolven). Drop het bestand in een project, wikkel het in je namespace, klaar.
Aan de praat krijgen
Voor puur DTO-gebruik zijn de classes klaar om te serialiseren met System.Text.Json of Newtonsoft.Json. Voor echt gRPC in C#-werk — service-implementaties, streaming, deadlines — blijf Grpc.Tools gebruiken voor de wire-format types, en gebruik deze converter voor handgeschreven wrappers, mappinglagen of test fixtures naast de gegenereerde code.
Wanneer dit echt tijd scheelt
DTOs schetsen voor een nieuwe gRPC-service
Je begint aan een ASP.NET Core gRPC-service en wil zien hoe de messages er in C# uit gaan zien voordat je je vastlegt op Grpc.Tools. Plak de .proto, scan de classes, beslis of de veldnaamgeving bij de stijl van je team past en zet de codegen daarna netjes op.
Handgeschreven mappinglaag
Je gegenereerde gRPC-types leven in hun eigen namespace en je wil schone DTOs voor je domeinlaag. De output hier geeft je nette classes zonder de metadata-rommel van gegenereerde code — makkelijk in en uit te mappen met AutoMapper of zelfgemaakte converters.
Een wijziging in een Protobuf-schema reviewen
Een teamgenoot heeft velden toegevoegd aan een message in een PR. Je wil de impact op de C#-vorm zien zonder de branch te checkouten en een build te draaien. Plak het nieuwe schema, diff met de huidige C#-types en laat een gerichte review-comment achter.
Test fixtures en snelle scripts
Je schrijft een eenmalig LinqPad-script of een console-app die naar een gRPC-gateway POSTet. Voor 50 regels testcode de hele Protobuf-toolchain optuigen is overdreven. Pak hier de classes, serialiseer naar JSON, stuur het request en ga door.
Veelgestelde vragen
Wordt mijn schema ergens naartoe gestuurd?
Nee. De parser en de C#-emitter draaien volledig in je browser als JavaScript. Open de DevTools en kijk naar het Network-tabblad terwijl je plakt — nul requests. Handig als je schema interne typenamen, package-paden of iets anders bevat dat je niet bij een derde partij wil hebben.
Werken deze classes met door Grpc.Tools gegenereerde code?
Ze leveren equivalente vormen op, maar niet byte-voor-byte identiek. Grpc.Tools genereert partial classes, parser-registraties, descriptor-bedrading en voorouder-types vanaf Google.Protobuf.IMessage — niets daarvan zit hierin. Voor echt gRPC-wireprotocol-werk: gebruik Grpc.Tools. Voor alleen-DTO-code (bijvoorbeeld JSON-over-HTTP-gateways, mappinglagen, testdata) is deze output prima.
Waarom worden int64 en uint64 als long en ulong getypeerd in plaats van als string?
Omdat ze in C# gewoon passen. Anders dan JavaScript Numbers (die boven 2^53 precisie verliezen), kan long in C# de hele int64-range native aan, dus geen reden om naar string terug te vallen. Als je proto3-JSON deserialiseert waarin 64-bit ints als strings binnenkomen (volgens de JSON-mappingspec), regelt System.Text.Json met JsonNumberHandling.AllowReadingFromString de conversie.
Hoe gaat het om met de SCREAMING_SNAKE-conventie voor enum-waarden?
De Protobuf-style guide raadt aan elke enum-waarde te prefixen met de enum-naam in SCREAMING_SNAKE. De converter detecteert dat en strip't het. ORDER_STATUS_UNSPECIFIED in enum OrderStatus wordt OrderStatus.Unspecified. Volgt je enum die conventie niet (sommige waarden geprefixed, andere niet), dan wordt het strippen overgeslagen en worden de waarden gewoon in PascalCase gezet.
Ondersteunt het oneof?
Elk veld van een oneof komt eruit als een gewone auto-property. De output dwingt de "precies één"-restrictie van oneof niet af — de C#-taal heeft nog geen native discriminated unions. Heb je strakkere modellering nodig, kijk dan naar libraries als OneOf op NuGet, of pas de output handmatig aan tot een baseclass met subclasses.
En google.protobuf.Timestamp en de well-known types?
Timestamp komt eruit als string (proto3-JSON encodeert timestamps als RFC 3339-strings). Empty en Any worden object-placeholders — pas ze aan naar Google.Protobuf.WellKnownTypes.Any of een sterker type als je project het WKT-pakket binnenhaalt. De output is bewust framework-vrij, zodat je hem in elk C#-project kunt droppen zonder een NuGet-afhankelijkheid op te dringen.
Gerelateerde tools
Als je aan het jongleren bent met Protobuf, JSON en C#, passen deze goed bij elkaar: