DevToolBoxGRATUIT
Blog

JSON vers Classe C# : Guide System.Text.Json, Newtonsoft et Records

17 min de lecturepar DevToolBox

La conversion de JSON en classes C# est une tache essentielle dans le developpement .NET moderne. Que vous construisiez une API ASP.NET Core, un jeu Unity, une application Blazor ou un client MAUI, vous avez besoin de classes C# fortement typees pour deserialiser les reponses JSON. Ce guide couvre le mapping des types, System.Text.Json, Newtonsoft.Json, les records, la generation POCO et les bonnes pratiques.

Essayez notre convertisseur gratuit JSON vers C# en ligne.

Qu'est-ce que la conversion JSON vers C# ?

JSON est le format d'echange de donnees universel pour les API web et les services cloud. C# etant un langage a typage statique, il necessite des definitions de classes explicites. La conversion JSON vers C# analyse un document JSON et produit les classes C# correspondantes avec des proprietes typees et des annotations de serialisation.

Dans une application ASP.NET Core typique, un controleur recoit un corps de requete HTTP en JSON. Le framework doit convertir ce JSON en objets C# a l'aide de System.Text.Json ou Newtonsoft.Json. Un convertisseur JSON vers C# automatise la creation de ces objets de transfert de donnees.

La meme conversion est essentielle dans Unity, Blazor et Azure Functions. Le processus est identique : inspecter la structure JSON, determiner les types, gerer l'imbrication et les tableaux.

JSON vers C# : Mapping des types

Comprendre comment les types JSON correspondent aux types C# est la base de toute conversion :

Type JSONExempleType(s) C#Notes
string"hello"stringToujours System.String
number (entier)42int, longint? si nullable
number (decimal)3.14double, decimaldecimal pour les donnees financieres
booleantrueboolbool? si nullable
nullnullnullTypes nullable
array[1,2]List<T>List prefere
object{"k":"v"}Classe imbriqueeClasses typees preferees

Lors de la generation de classes C# a partir de JSON, le choix entre types valeur et types nullable est important. Pour les valeurs monetaires, utilisez toujours decimal.

Comment fonctionne la conversion JSON vers C#

Un convertisseur JSON vers C# suit un processus systematique :

  1. Analyser la structure JSON : Construction d'un arbre syntaxique.
  2. Inferer les types : Determination du type C# pour chaque propriete.
  3. Generer les noms : Conversion en PascalCase.
  4. Gerer les objets imbriques : Chaque objet imbrique genere une classe separee.
  5. Gerer les tableaux : Analyse du type d'element.
  6. Ajouter les attributs : [JsonPropertyName] ou [JsonProperty].
  7. Produire le code source : Code C# formate.

Exemples de code : JSON vers C# avec System.Text.Json et Newtonsoft

System.Text.Json (.NET 8+) : JsonSerializer et attributs

System.Text.Json est le serialiseur JSON haute performance integre a .NET. Depuis .NET 8, il supporte les generateurs de source pour la compilation AOT :

// === Sample JSON ===
// {
//   "user_id": 1001,
//   "user_name": "Alice",
//   "email": "alice@example.com",
//   "is_active": true,
//   "balance": 1250.75,
//   "tags": ["admin", "developer"],
//   "address": {
//     "street": "123 Main St",
//     "city": "Springfield",
//     "zip_code": "62704"
//   }
// }

// === C# class with System.Text.Json attributes ===
using System.Text.Json;
using System.Text.Json.Serialization;

public class User
{
    [JsonPropertyName("user_id")]
    public long UserId { get; set; }

    [JsonPropertyName("user_name")]
    public string UserName { get; set; } = "";

    public string Email { get; set; } = "";

    [JsonPropertyName("is_active")]
    public bool IsActive { get; set; }

    public decimal Balance { get; set; }

    public List<string> Tags { get; set; } = new();

    public Address Address { get; set; } = new();
}

public class Address
{
    public string Street { get; set; } = "";
    public string City { get; set; } = "";

    [JsonPropertyName("zip_code")]
    public string ZipCode { get; set; } = "";
}

// === Deserialization with JsonSerializer ===
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

// Single object
User? user = JsonSerializer.Deserialize<User>(jsonString, options);

// List of objects
List<User>? users = JsonSerializer.Deserialize<List<User>>(
    jsonArrayString, options);

// === Custom JsonConverter for special cases ===
public class EpochToDateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(
        ref Utf8JsonReader reader, Type typeToConvert,
        JsonSerializerOptions options)
    {
        return DateTimeOffset.FromUnixTimeSeconds(
            reader.GetInt64()).DateTime;
    }

    public override void Write(
        Utf8JsonWriter writer, DateTime value,
        JsonSerializerOptions options)
    {
        writer.WriteNumberValue(
            new DateTimeOffset(value).ToUnixTimeSeconds());
    }
}

// Usage: [JsonConverter(typeof(EpochToDateTimeConverter))]
// public DateTime CreatedAt { get; set; }

// === .NET 8 Source Generator (AOT-friendly) ===
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(List<User>))]
public partial class AppJsonContext : JsonSerializerContext { }

// Zero-reflection deserialization:
User? u = JsonSerializer.Deserialize(
    jsonString, AppJsonContext.Default.User);

Newtonsoft.Json : JsonConvert et attributs

Newtonsoft.Json est le standard de fait pour la deserialisation JSON en C# avec JObject, LINQ-to-JSON et JsonConverter personnalise :

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;

public class User
{
    [JsonProperty("user_id")]
    public long UserId { get; set; }

    [JsonProperty("user_name")]
    public string UserName { get; set; } = "";

    public string Email { get; set; } = "";

    [JsonProperty("is_active")]
    public bool IsActive { get; set; }

    public decimal Balance { get; set; }

    public List<string> Tags { get; set; } = new();

    public Address Address { get; set; } = new();
}

// === Deserialization with JsonConvert ===
var settings = new JsonSerializerSettings
{
    MissingMemberHandling = MissingMemberHandling.Ignore,
    NullValueHandling = NullValueHandling.Ignore,
    DateFormatString = "yyyy-MM-ddTHH:mm:ssZ"
};

// Single object
User? user = JsonConvert.DeserializeObject<User>(
    jsonString, settings);

// List of objects
List<User>? users = JsonConvert.DeserializeObject<List<User>>(
    jsonArrayString, settings);

// === Dynamic parsing with JObject ===
JObject obj = JObject.Parse(jsonString);
string? name = (string?)obj["user_name"];
JArray? tags = (JArray?)obj["tags"];
int tagCount = tags?.Count ?? 0;

// LINQ-to-JSON queries
var activeUsers = JArray.Parse(jsonArrayString)
    .Where(u => (bool)u["is_active"]!)
    .Select(u => (string?)u["user_name"])
    .ToList();

// === Custom JsonConverter ===
public class BoolToIntConverter : JsonConverter<bool>
{
    public override bool ReadJson(
        JsonReader reader, Type objectType, bool existingValue,
        bool hasExistingValue, JsonSerializer serializer)
    {
        return Convert.ToInt32(reader.Value) == 1;
    }

    public override void WriteJson(
        JsonWriter writer, bool value,
        JsonSerializer serializer)
    {
        writer.WriteValue(value ? 1 : 0);
    }
}

// Usage: [JsonConverter(typeof(BoolToIntConverter))]
// public bool IsActive { get; set; }

Records C# : Modeles de donnees immuables

Les records C# 9+ offrent une facon concise de definir des modeles immuables avec Equals, GetHashCode et expressions with :

// C# Record classes for JSON deserialization (C# 9+)
using System.Text.Json.Serialization;

public record User(
    [property: JsonPropertyName("user_id")] long UserId,
    [property: JsonPropertyName("user_name")] string UserName,
    string Email,
    [property: JsonPropertyName("is_active")] bool IsActive,
    decimal Balance,
    List<string> Tags,
    Address Address
);

public record Address(
    string Street,
    string City,
    [property: JsonPropertyName("zip_code")] string ZipCode
);

// Deserialization works seamlessly with records
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
User? user = JsonSerializer.Deserialize<User>(json, options);

// Records are immutable: use "with" for modified copies
User updated = user! with { Email = "new@example.com" };

// Init-only record class (C# 10+)
public record class Product
{
    public required long Id { get; init; }
    public required string Name { get; init; }
    public required decimal Price { get; init; }
    public bool InStock { get; init; }
    public List<string> Categories { get; init; } = new();
}

// Value-based equality: two records with same data are equal
var p1 = new Product { Id = 1, Name = "Keyboard", Price = 79.99m };
var p2 = new Product { Id = 1, Name = "Keyboard", Price = 79.99m };
Console.WriteLine(p1 == p2);  // True

POCO manuel : Classe avec proprietes

Pour un controle total, un POCO traditionnel avec INotifyPropertyChanged ou AutoMapper offre une flexibilite maximale :

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;

// POCO with INotifyPropertyChanged for WPF/MAUI data binding
public class Product : INotifyPropertyChanged
{
    private long _id;
    private string _name = "";
    private decimal _price;
    private bool _inStock;
    private List<string> _categories = new();

    [JsonPropertyName("product_id")]
    public long Id
    {
        get => _id;
        set => SetField(ref _id, value);
    }

    public string Name
    {
        get => _name;
        set => SetField(ref _name, value);
    }

    public decimal Price
    {
        get => _price;
        set => SetField(ref _price, value);
    }

    [JsonPropertyName("in_stock")]
    public bool InStock
    {
        get => _inStock;
        set => SetField(ref _inStock, value);
    }

    public List<string> Categories
    {
        get => _categories;
        set => SetField(ref _categories, value);
    }

    // INotifyPropertyChanged implementation
    public event PropertyChangedEventHandler? PropertyChanged;

    private void OnPropertyChanged(
        [CallerMemberName] string? name = null)
    {
        PropertyChanged?.Invoke(
            this, new PropertyChangedEventArgs(name));
    }

    private bool SetField<T>(
        ref T field, T value,
        [CallerMemberName] string? name = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
            return false;
        field = value;
        OnPropertyChanged(name);
        return true;
    }

    // Override ToString for debugging
    public override string ToString()
        => $"Product {{ Id={Id}, Name={Name}, Price={Price} }}";
}

// Usage with AutoMapper (DTO to domain model):
// var config = new MapperConfiguration(cfg =>
//     cfg.CreateMap<ProductDto, Product>());
// var mapper = config.CreateMapper();
// Product product = mapper.Map<Product>(dto);

Travailler avec des structures JSON imbriquees

Les API reelles contiennent des objets profondement imbriques et des types polymorphes :

Objets imbriques : Chaque niveau d'imbrication produit une classe C# separee.

Tableaux d'objets : "items": [{"id": 1}] correspond a List<Item>.

Deserialisation polymorphe : .NET 7+ supporte [JsonDerivedType] et [JsonPolymorphic].

// Polymorphic deserialization with .NET 7+ System.Text.Json
using System.Text.Json.Serialization;

[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(EmailNotification), "email")]
[JsonDerivedType(typeof(SmsNotification), "sms")]
[JsonDerivedType(typeof(PushNotification), "push")]
public abstract class Notification
{
    public string Type { get; set; } = "";
    public string Message { get; set; } = "";
    public DateTime CreatedAt { get; set; }
}

public class EmailNotification : Notification
{
    public string Recipient { get; set; } = "";
    public string Subject { get; set; } = "";
}

public class SmsNotification : Notification
{
    public string PhoneNumber { get; set; } = "";
}

public class PushNotification : Notification
{
    public string DeviceToken { get; set; } = "";
    public string Title { get; set; } = "";
}

// JSON input:
// {"type":"email","message":"Hello","recipient":"a@b.com","subject":"Hi"}
// Automatically deserializes to EmailNotification

// Nested classes with arrays example
public class ApiResponse
{
    public bool Success { get; set; }
    public UserData Data { get; set; } = new();
    public List<ErrorDetail> Errors { get; set; } = new();
}

public class UserData
{
    public User User { get; set; } = new();
    public List<Order> Orders { get; set; } = new();
    public Address BillingAddress { get; set; } = new();
    public Address ShippingAddress { get; set; } = new();
}

public class Order
{
    public long OrderId { get; set; }
    public decimal Total { get; set; }
    public List<OrderItem> Items { get; set; } = new();
}

public class OrderItem
{
    public long ProductId { get; set; }
    public string Name { get; set; } = "";
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
}

Patterns avances : Generateurs de source, AOT et types nullable

Les generateurs de source .NET 8 pour System.Text.Json produisent du code de serialisation a la compilation, eliminant la reflexion et permettant le deploiement AOT natif :

// .NET 8 Source Generator for AOT-friendly serialization
using System.Text.Json;
using System.Text.Json.Serialization;

public record Product(
    [property: JsonPropertyName("product_id")] long ProductId,
    string Name,
    decimal Price,
    [property: JsonPropertyName("in_stock")] bool InStock,
    List<string> Tags,
    [property: JsonPropertyName("created_at")] DateTime CreatedAt
);

// Source generator context
[JsonSerializable(typeof(Product))]
[JsonSerializable(typeof(List<Product>))]
[JsonSourceGenerationOptions(
    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    GenerationMode = JsonSourceGenerationMode.Default)]
public partial class AppJsonContext : JsonSerializerContext { }

// Zero-reflection serialization (AOT-compatible)
var product = JsonSerializer.Deserialize(
    json, AppJsonContext.Default.Product);
var jsonOut = JsonSerializer.Serialize(
    product, AppJsonContext.Default.Product);

// Works with ASP.NET Core minimal APIs
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain
        .Insert(0, AppJsonContext.Default);
});

Les types reference nullable C# 8+ fournissent la securite null a la compilation. Combinez avec les proprietes required (C# 11+) :

// Nullable reference types + required properties (C# 11+)
#nullable enable

public class UserProfile
{
    public required string Name { get; init; }
    public required string Email { get; init; }
    public string? Nickname { get; init; }     // optional
    public int Age { get; init; }
    public string? AvatarUrl { get; init; }     // optional
    public required List<string> Roles { get; init; }
}

// Deserialization enforces required properties
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
var user = JsonSerializer.Deserialize<UserProfile>(json, options)
    ?? throw new InvalidOperationException(
        "Failed to deserialize user profile");

// Compiler warning if you forget to set required properties:
// var profile = new UserProfile { Name = "Alice" };
// Error CS9035: Required member 'Email' must be set

// JsonRequired attribute for runtime enforcement
public class StrictModel
{
    [JsonRequired]
    public string Id { get; set; } = "";

    [JsonRequired]
    public string Name { get; set; } = "";

    public string? Description { get; set; }
}

System.Text.Json vs Newtonsoft : System.Text.Json est 2-5x plus rapide, utilise moins de memoire et supporte les generateurs de source. Newtonsoft offre plus de fonctionnalites.

Bonnes pratiques pour la conversion JSON vers C#

Suivez ces bonnes pratiques pour des applications .NET robustes :

Proprietes PascalCase avec attributs : Utilisez [JsonPropertyName] pour mapper les cles JSON.

Activez les types nullable : #nullable enable pour la securite null a la compilation.

Gerez les proprietes inconnues : System.Text.Json les ignore par defaut. Configurez Newtonsoft avec MissingMemberHandling.Ignore.

Decimal pour les valeurs monetaires : N'utilisez jamais float ou double pour l'argent.

Preferez les records pour les DTO : Records avec proprietes init-only pour l'immutabilite.

Generateurs de source pour la performance : [JsonSerializable] dans .NET 8+.

Validez les donnees deserialisees : Annotations de donnees ou FluentValidation.

Outils connexes : JSON vers Java, JSON vers TypeScript, JSON vers Kotlin.

JSON to JavaJSON to TypeScriptJSON to Kotlin

Questions frequemment posees

System.Text.Json ou Newtonsoft : lequel utiliser ?

System.Text.Json est recommande pour les nouveaux projets .NET 8+. Il est integre, 2-5x plus rapide et supporte les generateurs de source AOT. Newtonsoft reste utile pour les projets existants et les scenarios complexes avec JObject.

Records C# ou classes traditionnelles ?

Utilisez les records pour les DTO immuables (C# 9+). Utilisez les classes pour la mutabilite ou INotifyPropertyChanged. Pour ASP.NET Core, les records sont la pratique moderne.

Comment gerer les proprietes JSON inconnues ?

System.Text.Json les ignore par defaut. Pour les capturer, utilisez [JsonExtensionData]. Newtonsoft leve une exception par defaut, configurez MissingMemberHandling.Ignore.

La conversion JSON vers C# est une competence fondamentale. Utilisez notre outil gratuit pour une generation instantanee.

Convertissez JSON en classes C# instantanement avec notre outil gratuit.

𝕏 Twitterin LinkedIn
Cet article vous a-t-il aidé ?

Restez informé

Recevez des astuces dev et les nouveaux outils chaque semaine.

Pas de spam. Désabonnez-vous à tout moment.

Essayez ces outils associés

C#JSON to C#JVJSON to Java ClassTSJSON to TypeScript{ }JSON Formatter

Articles connexes

Convertisseur JSON vers Classe Java : Guide POJO, Jackson, Gson et Lombok

Convertir JSON en classe Java en ligne. Apprenez a generer des POJO avec Jackson, Gson et Lombok avec des exemples de code.

JSON vers TypeScript : Guide complet avec exemples

Apprenez à convertir automatiquement des données JSON en interfaces TypeScript. Objets imbriqués, tableaux, champs optionnels et bonnes pratiques.

JSON vers Kotlin Data Class : Guide kotlinx.serialization, Moshi et Gson

Convertir JSON en data class Kotlin en ligne. Apprenez le parsing JSON avec kotlinx.serialization, Moshi et Gson.