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_idOrderId, shipping_addressShippingAddress — 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.

1

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).

2

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.

3

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: