Protobuf til C#-konverter
Indsæt et .proto-skema. Få C#-klasser med auto-properties — kan smides direkte ind i et projekt, ingen protoc-plugin nødvendig.
Input (.proto-skema)
Output (C#)
Hvad værktøjet gør
Du har et Protocol Buffers-skema og en C#-service eller -klient, der har brug for de matchende DTO'er. Den officielle vej er at installere protoc med C#-pluginnet (eller koble Grpc.Tools ind i dit .csproj) og lade MSBuild generere partial-klasserne under build. Det virker, men det er overkill, når du bare vil læse skemaet, skitsere typer eller indsætte en message i en Razor-side eller en engangsintegration. Denne konverter laver samme slags arbejde — indsæt, kopiér, smid det i Types.cs.
Type-mappingen er af den kedelige-men-korrekte slags. string bliver ved med at være string (med initialiseren = "", så projekter med nullable references ikke brokker sig). bool, int32, int64, uint32, uint64, float, double mapper til bool, int, long, uint, ulong, float, double i nævnte rækkefølge. bytes bliver til byte[]. repeated T bliver til List<T>, map<K, V> bliver til Dictionary<K, V>, og kendte wrappers som google.protobuf.Timestamp skrives ud som string (proto3 JSON-kodningen for tidsstempler er RFC 3339, hvilket på wire-niveau bare er en streng — se proto3 JSON-specifikationen, hvis du vil have detaljerne).
Feltnavne får standard-PascalCase-behandlingen — order_id → OrderId, shipping_address → ShippingAddress — som matcher det, den officielle C# protobuf-reference genererer. Enum-værdier mister deres SCREAMING_SNAKE-præfiks, når skemaet følger konventionen om at præfikse hver værdi med enum-navnet (så ORDER_STATUS_PENDING i enum OrderStatus bliver til OrderStatus.Pending). Output-klasserne er flade — alle nestede messages løftes op til top-level, så du kan dele dem op eller flytte rundt på dem uden at hive scopes fra hinanden. Konverteringen foregår udelukkende i din browser; intet fra skemaet bliver uploadet.
Sådan bruger du det
Tre trin. Outputtet er klar til at blive kompileret — indsæt det i en <code>Types.cs</code>-fil i dit projekt.
Indsæt dit .proto-skema
Smid skemaet ind i editoren til venstre. syntax = "proto3"; i toppen er valgfrit. Parseren håndterer nestede message-blokke, enum-deklarationer, oneof, map<K, V>, feltoptions og de sædvanlige package/import/option-direktiver. Imports genkendes, men springes over, så indsæt importerede typer inline, hvis dit skema afhænger af dem.
Konverteringen af feltnavne sker automatisk: customer_name i .proto bliver til CustomerName i C#. Klasse- og enum-navne forbliver som de er (allerede PascalCase efter konvention).
Læs outputtet
Til højre: public class-deklarationer med { get; set; }-auto-properties for hver message, plus public enum-deklarationer for hver enum. En using System.Collections.Generic;-linje tilføjes, når skemaet bruger repeated- eller map-felter (så List og Dictionary kan resolve). Smid filen ind i et projekt, pak det ind i din namespace, og du er færdig.
Sæt det op
Til ren DTO-brug er klasserne klar til at blive serialiseret med System.Text.Json eller Newtonsoft.Json. Til rigtigt gRPC C#-arbejde — service-implementeringer, streaming, deadlines — bliv ved med at bruge Grpc.Tools til wire-format-typerne, og brug denne konverter til håndskrevne wrappers, mapping-lag eller test-fixtures ved siden af den genererede kode.
Hvornår det faktisk sparer tid
Skitsere DTO'er til en ny gRPC-service
Du starter en ASP.NET Core gRPC-service og vil se, hvordan messages kommer til at se ud i C#, før du committer til Grpc.Tools. Indsæt .proto, kig klasserne igennem, beslut om feltnavngivningen passer til teamets stil, og sæt så codegen op ordentligt.
Håndskrevet mapping-lag
Dine genererede gRPC-typer bor i deres egen namespace, og du vil have rene DTO'er til dit domænelag. Outputtet her giver dig pæne klasser uden metadata-rodet fra genereret kode — nemt at mappe frem og tilbage med AutoMapper eller egne konvertere.
Gennemgå en Protobuf-skemaændring
En holdkammerat tilføjede felter til en message i en PR. Du vil se konsekvenserne for C#-formen uden at checke branchen ud og køre et build. Indsæt det nye skema, lav diff mod de nuværende C#-typer, og efterlad en målrettet review-kommentar.
Test-fixtures og hurtige scripts
Du skriver et engangs-LinqPad-script eller en konsol-app, der POST'er til en gRPC-gateway. At sætte hele Protobuf-toolchainen op for 50 linjer testkode er overkill. Tag klasserne herfra, serialiser dem til JSON, send requestet, og gå videre.
Almindelige spørgsmål
Bliver mit skema sendt nogen steder hen?
Nej. Parseren og C#-emitteren kører udelukkende i din browser som JavaScript. Åbn DevTools og hold øje med Network-fanen, mens du indsætter — nul requests. Praktisk, når dit skema indeholder interne typenavne, package-stier eller andet, du ikke ville sende til en tredjepartstjeneste.
Virker disse klasser med Grpc.Tools-genereret kode?
De producerer ækvivalente former, men er ikke byte-for-byte identiske. Grpc.Tools genererer partial-klasser, parser-registreringer, descriptor-wiring og forfædretyper fra Google.Protobuf.IMessage — intet af det er her. Til rigtigt gRPC-wire-protokol-arbejde: brug Grpc.Tools. Til kun-DTO-kode (fx JSON-over-HTTP-gateways, mapping-lag, testdata) kan dette output sagtens bruges.
Hvorfor er int64 og uint64 typet som long og ulong i stedet for string?
Fordi de passer i C#. Modsat JavaScript-Numbers (som mister præcision over 2^53) håndterer C# long hele int64-intervallet nativt, så der er ingen grund til at falde tilbage til string. Hvis du deserialiserer proto3-JSON, hvor 64-bit ints kommer som strenge (efter JSON-mapping-specifikationen), klarer System.Text.Json med JsonNumberHandling.AllowReadingFromString konverteringen.
Hvordan håndterer den SCREAMING_SNAKE-konventionen for enum-værdier?
Protobuf-style-guiden anbefaler at præfikse hver enum-værdi med enum-navnet i SCREAMING_SNAKE. Konverteren registrerer det og fjerner præfikset. ORDER_STATUS_UNSPECIFIED i enum OrderStatus bliver til OrderStatus.Unspecified. Hvis dit enum ikke følger konventionen (nogle værdier præfikset, andre ikke), springes præfiks-fjernelsen over, og værdierne PascalCase's som de er.
Håndterer den oneof?
Hvert oneof-felt skrives ud som en almindelig auto-property. Outputtet håndhæver ikke "præcis ét"-restriktionen, som oneof antyder — sproget C# har endnu ikke native discriminated unions. Hvis du har brug for strammere modellering, kig på biblioteker som OneOf på NuGet, eller rediger outputtet manuelt til en basisklasse plus subklasser.
Hvad med google.protobuf.Timestamp og well-known types?
Timestamp skrives ud som string (proto3-JSON koder tidsstempler som RFC 3339-strenge). Empty og Any bliver til object-pladsholdere — justér til Google.Protobuf.WellKnownTypes.Any eller en stærkere type, hvis dit projekt henter WKT-pakken ind. Outputtet er bevidst framework-frit, så du kan smide det ind i ethvert C#-projekt uden at tvinge en NuGet-afhængighed.
Relaterede værktøjer
Hvis du jonglerer mellem Protobuf, JSON og C#, passer disse fint sammen: