Convertisseur Protobuf vers C#
Collez un schéma .proto. Récupérez des classes C# avec auto-properties — prêtes à être déposées directement dans un projet, sans plugin protoc.
Entrée (schéma .proto)
Sortie (C#)
Ce que fait cet outil
Vous avez un schéma Protocol Buffers et un service ou client C# qui a besoin des DTOs correspondants. La voie officielle, c'est d'installer protoc avec le plugin C# (ou de brancher Grpc.Tools dans votre .csproj) et de laisser MSBuild générer les classes partielles à la compilation. Ça marche, mais c'est exagéré quand vous voulez juste lire le schéma, esquisser des types, ou coller un message dans une page Razor ou une intégration ponctuelle. Ce convertisseur fait le même genre de boulot — collez, copiez, déposez dans Types.cs.
Le mapping de types est du genre ennuyeux mais correct. string reste string (avec un initialiseur = "" pour que les projets en nullable reference ne râlent pas). bool, int32, int64, uint32, uint64, float, double se mappent vers bool, int, long, uint, ulong, float, double respectivement. bytes devient byte[]. repeated T devient List<T>, map<K, V> devient Dictionary<K, V>, et les wrappers bien connus comme google.protobuf.Timestamp sont émis en string (l'encodage JSON proto3 des timestamps est du RFC 3339, soit juste une chaîne au niveau du wire — voir la spec JSON proto3 pour les détails).
Les noms de champs reçoivent le traitement PascalCase classique — order_id → OrderId, shipping_address → ShippingAddress — comme ce que génère la référence officielle protobuf C#. Les valeurs d'enum perdent leur préfixe SCREAMING_SNAKE quand le schéma suit la convention de préfixer chaque valeur avec le nom de l'enum (donc ORDER_STATUS_PENDING dans enum OrderStatus devient OrderStatus.Pending). Les classes en sortie sont à plat — chaque message imbriqué est remonté au niveau supérieur pour que vous puissiez les séparer ou les réorganiser sans démêler les portées. La conversion se passe entièrement dans votre navigateur ; rien du schéma n'est envoyé ailleurs.
Comment l'utiliser
Trois étapes. La sortie est prête à compiler — collez-la dans un fichier <code>Types.cs</code> de votre projet.
Collez votre schéma .proto
Déposez le schéma dans l'éditeur de gauche. syntax = "proto3"; en tête est optionnel. Le parser gère les blocs message imbriqués, les déclarations enum, oneof, map<K, V>, les options de champ et les directives habituelles package/import/option. Les imports sont reconnus mais ignorés, donc collez les types importés inline si votre schéma en dépend.
La conversion des noms de champs est automatique : customer_name dans .proto devient CustomerName en C#. Les noms de classes et d'enums sont laissés tels quels (déjà en PascalCase par convention).
Lisez la sortie
À droite : des déclarations public class avec des auto-properties { get; set; } pour chaque message, plus des déclarations public enum pour chaque enum. Une ligne using System.Collections.Generic; est ajoutée quand le schéma utilise des champs repeated ou map (pour que List et Dictionary se résolvent). Déposez le fichier dans un projet, enveloppez-le dans votre namespace, c'est fini.
Branchez le tout
Pour un usage purement DTO, les classes sont prêtes à être sérialisées avec System.Text.Json ou Newtonsoft.Json. Pour du vrai travail gRPC C# — implémentations de service, streaming, deadlines — gardez Grpc.Tools pour les types wire-format, et utilisez ce convertisseur pour les wrappers écrits à la main, les couches de mapping ou les fixtures de tests aux côtés du code généré.
Quand ça fait vraiment gagner du temps
Esquisser des DTOs pour un nouveau service gRPC
Vous démarrez un service gRPC ASP.NET Core et vous voulez voir à quoi vont ressembler les messages en C# avant de vous engager avec Grpc.Tools. Collez le .proto, regardez les classes, décidez si le nommage des champs colle au style de l'équipe, puis branchez la génération de code proprement.
Couche de mapping écrite à la main
Vos types gRPC générés vivent dans leur propre namespace et vous voulez des DTOs sobres pour votre couche domaine. La sortie d'ici vous donne des classes propres sans le bruit des métadonnées du code généré — facile à mapper avec AutoMapper ou des convertisseurs faits maison.
Relire un changement de schéma Protobuf
Un coéquipier a ajouté des champs à un message dans une PR. Vous voulez voir l'impact sur la forme C# sans checker la branche et lancer un build. Collez le nouveau schéma, faites un diff avec les types C# actuels, laissez un commentaire de revue ciblé.
Fixtures de tests et scripts rapides
Vous écrivez un script LinqPad ponctuel ou une app console qui POST vers un gRPC-gateway. Brancher tout le toolchain Protobuf pour 50 lignes de code de test, c'est exagéré. Récupérez les classes ici, sérialisez-les en JSON, envoyez la requête, passez à autre chose.
Questions fréquentes
Mon schéma est-il envoyé quelque part ?
Non. Le parser et l'émetteur C# tournent entièrement dans votre navigateur en JavaScript. Ouvrez les DevTools et regardez l'onglet Network pendant que vous collez — zéro requête. Pratique quand votre schéma contient des noms de types internes, des chemins de package ou autre chose que vous ne voudriez pas envoyer à un service tiers.
Ces classes fonctionnent-elles avec le code généré par Grpc.Tools ?
Elles produisent des formes équivalentes, mais pas identiques octet pour octet. Grpc.Tools génère des classes partielles, des enregistrements de parser, du câblage de descriptor et des types ancêtres depuis Google.Protobuf.IMessage — rien de tout ça ici. Pour le vrai travail au protocole wire gRPC, utilisez Grpc.Tools. Pour du code uniquement DTO (par ex. gateways JSON-sur-HTTP, couches de mapping, données de test), cette sortie convient.
Pourquoi int64 et uint64 sont-ils typés long et ulong au lieu de string ?
Parce qu'en C# ils tiennent. Contrairement aux Number de JavaScript (qui perdent en précision au-dessus de 2^53), le long de C# gère nativement toute la plage int64, donc aucune raison de retomber sur string. Si vous désérialisez du JSON proto3 où les entiers 64 bits arrivent en chaînes (selon la spec de mapping JSON), System.Text.Json avec JsonNumberHandling.AllowReadingFromString gère la conversion.
Comment est gérée la convention de valeurs d'enum en SCREAMING_SNAKE ?
Le guide de style Protobuf recommande de préfixer chaque valeur d'enum avec le nom de l'enum en SCREAMING_SNAKE. Le convertisseur le détecte et l'enlève. ORDER_STATUS_UNSPECIFIED dans l'enum OrderStatus devient OrderStatus.Unspecified. Si votre enum ne suit pas cette convention (certaines valeurs préfixées, d'autres non), le strip de préfixe est sauté et les valeurs sont mises en PascalCase telles quelles.
Gère-t-il oneof ?
Chaque champ de oneof est émis comme une auto-property classique. La sortie n'impose pas la contrainte « exactement un » qu'implique oneof — le langage C# n'a pas encore d'unions discriminées natives. Si vous avez besoin d'une modélisation plus stricte, regardez les bibliothèques comme OneOf sur NuGet, ou éditez la sortie à la main pour utiliser une classe de base et des sous-classes.
Et google.protobuf.Timestamp et les well-known types ?
Timestamp est émis en string (le JSON proto3 encode les timestamps en chaînes RFC 3339). Empty et Any deviennent des placeholders object — ajustez-les en Google.Protobuf.WellKnownTypes.Any ou un type plus fort si votre projet tire le package WKT. La sortie est volontairement sans framework pour que vous puissiez la déposer dans n'importe quel projet C# sans forcer une dépendance NuGet.
Outils associés
Si vous jonglez entre Protobuf, JSON et C#, ces outils vont bien ensemble :