Convertitore Protobuf → C#
Incolla uno schema .proto. Ottieni classi C# con auto-property — pronte da buttare in un progetto, senza plugin protoc.
Input (schema .proto)
Output (C#)
Cosa fa questo strumento
Hai uno schema Protocol Buffers e un servizio o client C# che ha bisogno dei DTO corrispondenti. La via ufficiale è installare protoc col plugin C# (oppure agganciare Grpc.Tools al tuo .csproj) e lasciare che MSBuild generi le classi parziali in fase di build. Funziona, ma è esagerato quando vuoi solo leggere lo schema, abbozzare i tipi o incollare un messaggio in una pagina Razor o in un'integrazione una tantum. Questo convertitore fa lo stesso tipo di lavoro — incolla, copia, butta dentro Types.cs.
Il mapping dei tipi è del tipo noioso ma corretto. string resta string (con inizializzatore = "" per non far protestare i progetti con nullable reference type). bool, int32, int64, uint32, uint64, float, double mappano rispettivamente su bool, int, long, uint, ulong, float, double. bytes diventa byte[]. repeated T diventa List<T>, map<K, V> diventa Dictionary<K, V>, e i wrapper noti come google.protobuf.Timestamp vengono emessi come string (la codifica JSON di proto3 per i timestamp è RFC 3339, che a livello di wire è solo una stringa — vedi la spec JSON di proto3 per i dettagli).
I nomi dei campi ricevono il trattamento PascalCase standard — order_id → OrderId, shipping_address → ShippingAddress — coerente con quanto genera la reference protobuf C# ufficiale. I valori degli enum perdono il prefisso SCREAMING_SNAKE quando lo schema segue la convenzione di prefissare ogni valore col nome dell'enum (così ORDER_STATUS_PENDING in enum OrderStatus diventa OrderStatus.Pending). Le classi in output sono piatte — ogni messaggio annidato viene risalito al top-level, così puoi separarli o riordinarli senza districare gli scope. La conversione avviene tutta nel tuo browser; nulla dello schema viene caricato altrove.
Come usarlo
Tre passi. L'output è pronto per la compilazione — incollalo in un file <code>Types.cs</code> del tuo progetto.
Incolla lo schema .proto
Lascia cadere lo schema nell'editor di sinistra. syntax = "proto3"; in cima è opzionale. Il parser gestisce blocchi message annidati, dichiarazioni enum, oneof, map<K, V>, opzioni di campo e le solite direttive package/import/option. Gli import vengono riconosciuti ma saltati, quindi incolla inline i tipi importati se il tuo schema dipende da loro.
La conversione dei nomi di campo è automatica: customer_name nel .proto diventa CustomerName in C#. I nomi delle classi e degli enum restano com'erano (per convenzione già in PascalCase).
Leggi l'output
A destra: dichiarazioni public class con auto-property { get; set; } per ogni messaggio, più dichiarazioni public enum per ogni enum. Una riga using System.Collections.Generic; viene aggiunta quando lo schema usa campi repeated o map (così List e Dictionary si risolvono). Butta il file in un progetto, avvolgilo nel tuo namespace, fatto.
Collega tutto
Per uso solo come DTO, le classi sono pronte da serializzare con System.Text.Json o Newtonsoft.Json. Per il vero lavoro gRPC in C# — implementazioni di servizio, streaming, deadline — continua a usare Grpc.Tools per i tipi wire-format e usa questo convertitore per wrapper scritti a mano, layer di mapping o fixture di test affiancati al codice generato.
Quando fa risparmiare davvero tempo
Abbozzare DTO per un nuovo servizio gRPC
Stai avviando un servizio gRPC su ASP.NET Core e vuoi vedere come saranno fatti i messaggi in C# prima di impegnarti con Grpc.Tools. Incolla il .proto, dai un'occhiata alle classi, decidi se i nomi dei campi rispecchiano lo stile del tuo team, poi attacca la code generation per davvero.
Layer di mapping scritto a mano
I tuoi tipi gRPC generati vivono nel loro namespace e vuoi DTO puliti per il livello dominio. L'output qui ti dà classi pulite senza il rumore di metadati del codice generato — facili da mappare avanti e indietro con AutoMapper o convertitori artigianali.
Rivedere una modifica a uno schema Protobuf
Un collega ha aggiunto campi a un messaggio in una PR. Vuoi vedere l'impatto sulla forma C# senza fare checkout del branch e lanciare una build. Incolla lo schema nuovo, fai il diff con i tipi C# attuali, lascia un commento di review mirato.
Fixture di test e script veloci
Stai scrivendo uno script LinqPad usa-e-getta o un'app console che fa POST verso un gRPC-gateway. Tirare su tutta la toolchain Protobuf per 50 righe di codice di test è esagerato. Pesca le classi da qui, serializzale in JSON, manda la richiesta, vai avanti.
Domande frequenti
Il mio schema viene mandato da qualche parte?
No. Il parser e l'emettitore C# girano interamente nel tuo browser come JavaScript. Apri i DevTools e guarda la tab Network mentre incolli — zero richieste. Utile quando lo schema include nomi di tipi interni, percorsi di package o qualunque cosa non vorresti spedire a un servizio terzo.
Queste classi funzionano col codice generato da Grpc.Tools?
Producono forme equivalenti, ma non identiche byte per byte. Grpc.Tools genera classi parziali, registrazioni del parser, cablaggio dei descriptor e tipi antenati da Google.Protobuf.IMessage — niente di tutto questo è qui. Per il vero lavoro sul protocollo wire gRPC, usa Grpc.Tools. Per codice solo DTO (gateway JSON-su-HTTP, layer di mapping, dati di test), questo output va benissimo.
Perché int64 e uint64 sono tipizzati come long e ulong invece che come string?
Perché in C# ci stanno. A differenza dei Number di JavaScript (che perdono precisione sopra 2^53), long in C# gestisce nativamente l'intero range int64, quindi non c'è motivo di ripiegare su string. Se stai deserializzando JSON proto3 in cui gli interi a 64 bit arrivano come stringhe (per la spec di mapping JSON), System.Text.Json con JsonNumberHandling.AllowReadingFromString si occupa della conversione.
Come gestisce la convenzione dei valori enum SCREAMING_SNAKE?
La style guide di Protobuf raccomanda di prefissare ogni valore di enum col nome dell'enum in SCREAMING_SNAKE. Il convertitore lo rileva e lo rimuove. ORDER_STATUS_UNSPECIFIED nell'enum OrderStatus diventa OrderStatus.Unspecified. Se il tuo enum non segue la convenzione (alcuni valori prefissati, altri no), lo strip del prefisso viene saltato e i valori vengono messi in PascalCase così come sono.
Gestisce oneof?
Ogni campo di un oneof viene emesso come una normale auto-property. L'output non impone il vincolo "esattamente uno" che oneof implica — il linguaggio C# non ha ancora discriminated union nativi. Se ti serve una modellazione più stretta, dai un'occhiata a librerie come OneOf su NuGet, oppure modifica l'output a mano per usare una classe base con sottoclassi.
E google.protobuf.Timestamp e i well-known type?
Timestamp viene emesso come string (proto3 JSON codifica i timestamp come stringhe RFC 3339). Empty e Any diventano placeholder object — sostituiscili con Google.Protobuf.WellKnownTypes.Any o un tipo più forte se il tuo progetto tira dentro il pacchetto WKT. L'output è di proposito senza framework, così puoi buttarlo in qualsiasi progetto C# senza forzare una dipendenza NuGet.
Strumenti correlati
Se stai facendo i salti mortali tra Protobuf, JSON e C#, questi si abbinano bene: