DevToolBoxKOSTENLOS
Blog

JSON zu C#-Klasse: System.Text.Json, Newtonsoft & Records Anleitung

17 Min. Lesezeitvon DevToolBox

Die Konvertierung von JSON in C#-Klassen ist eine wesentliche Aufgabe in der modernen .NET-Entwicklung. Ob Sie eine ASP.NET Core Web-API, ein Unity-Spiel, eine Blazor-App oder einen MAUI-Client erstellen, Sie benotigen stark typisierte C#-Klassen zur Deserialisierung von JSON-Antworten. Dieser Leitfaden behandelt Typ-Mapping, System.Text.Json, Newtonsoft.Json, Records, POCO-Generierung und Best Practices.

Testen Sie unseren kostenlosen Online JSON-zu-C#-Konverter.

Was ist JSON-zu-C#-Klassenkonvertierung?

JSON ist das universelle Datenaustauschformat fur Web-APIs und Cloud-Dienste. C# als statisch typisierte Sprache erfordert explizite Klassendefinitionen. Die JSON-zu-C#-Konvertierung analysiert ein JSON-Dokument und erzeugt entsprechende C#-Klassen mit typisierten Eigenschaften und Serialisierungsattributen.

In einer typischen ASP.NET Core-Anwendung empfangt ein Controller den HTTP-Request-Body als JSON-String. Das Framework muss dieses JSON mit System.Text.Json oder Newtonsoft.Json in C#-Objekte konvertieren. Ein JSON-zu-C#-Konverter automatisiert die Erstellung dieser Datenobjekte.

Die gleiche Konvertierung ist in Unity, Blazor und Azure Functions wesentlich. Der Prozess ist identisch: JSON-Struktur inspizieren, Typen bestimmen, Verschachtelung und Arrays behandeln.

JSON zu C#: Typ-Mapping

Das Verstandnis der Zuordnung von JSON-Typen zu C#-Typen ist die Grundlage jeder Konvertierung:

JSON-TypBeispielC#-Typ(en)Hinweise
string"hello"stringImmer System.String
number (ganzzahlig)42int, longint? wenn nullable
number (dezimal)3.14double, decimaldecimal fur Finanzdaten
booleantrueboolbool? wenn nullable
nullnullnullNullable-Typen
array[1,2]List<T>List bevorzugt
object{"k":"v"}Verschachtelte KlasseStark typisierte Klassen bevorzugt

Bei der Generierung von C#-Klassen aus JSON ist die Wahl zwischen Werttypen und Nullable-Typen wichtig. Fur Geldwerte immer decimal verwenden.

Wie die JSON-zu-C#-Konvertierung funktioniert

Ein JSON-zu-C#-Konverter folgt einem systematischen Prozess:

  1. JSON-Struktur parsen: Aufbau eines Syntaxbaums.
  2. Eigenschaftstypen ableiten: C#-Typ fur jede Eigenschaft bestimmen.
  3. Namen generieren: Konvertierung in PascalCase.
  4. Verschachtelte Objekte behandeln: Jedes verschachtelte Objekt erzeugt eine separate Klasse.
  5. Arrays behandeln: Elementtyp-Analyse.
  6. Attribute hinzufugen: [JsonPropertyName] oder [JsonProperty].
  7. Quellcode ausgeben: Formatierter C#-Code.

Codebeispiele: JSON zu C# mit System.Text.Json und Newtonsoft

System.Text.Json (.NET 8+): JsonSerializer und Attribute

System.Text.Json ist der integrierte Hochleistungs-JSON-Serialisierer in .NET. Ab .NET 8 mit Quellgeneratoren fur AOT-Kompilierung:

// === 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 und Attribute

Newtonsoft.Json ist der De-facto-Standard fur C# JSON-Deserialisierung mit JObject, LINQ-to-JSON und benutzerdefinierten JsonConverter:

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; }

C# Records: Unveranderliche Datenmodelle

C# 9+ Records bieten eine kompakte Art, unveranderliche Datenmodelle zu definieren mit Equals, GetHashCode und with-Ausdrucken:

// 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

Manuelles POCO: Klasse mit Eigenschaften

Fur volle Kontrolle bietet ein traditionelles POCO mit INotifyPropertyChanged oder AutoMapper maximale Flexibilitat:

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

Arbeiten mit verschachtelten JSON-Strukturen

Reale APIs enthalten tief verschachtelte Objekte und polymorphe Typen:

Verschachtelte Objekte: Jede Verschachtelungsebene erzeugt eine separate C#-Klasse.

Objekt-Arrays: "items": [{"id": 1}] wird zu List<Item>.

Polymorphe Deserialisierung: .NET 7+ unterstutzt [JsonDerivedType] und [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; }
}

Fortgeschrittene Muster: Quellgeneratoren, AOT und Nullable-Typen

.NET 8 Quellgeneratoren fur System.Text.Json erzeugen Serialisierungscode zur Kompilierzeit und ermoglichen Native-AOT-Bereitstellung:

// .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);
});

Nullable-Referenztypen in C# 8+ bieten Kompilierzeit-Null-Sicherheit. Kombiniert mit required-Eigenschaften (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 ist 2-5x schneller, braucht weniger Speicher und unterstutzt Quellgeneratoren. Newtonsoft bietet mehr Funktionen.

Best Practices fur JSON-zu-C#-Konvertierung

Befolgen Sie diese Best Practices fur robuste .NET-Anwendungen:

PascalCase-Eigenschaften mit Attributen: [JsonPropertyName] fur JSON-Key-Mapping.

Nullable-Typen aktivieren: #nullable enable fur Kompilierzeit-Null-Sicherheit.

Unbekannte Eigenschaften behandeln: System.Text.Json ignoriert sie standardmassig. Newtonsoft mit MissingMemberHandling.Ignore konfigurieren.

Decimal fur Geldwerte: Niemals float oder double fur Geld.

Records fur DTOs bevorzugen: Records mit init-only-Eigenschaften fur Unveranderlichkeit.

Quellgeneratoren fur Performance: [JsonSerializable] in .NET 8+.

Deserialisierte Daten validieren: Datenannnotationen oder FluentValidation.

Verwandte Tools: JSON zu Java, JSON zu TypeScript, JSON zu Kotlin.

JSON to JavaJSON to TypeScriptJSON to Kotlin

Haufig gestellte Fragen

System.Text.Json oder Newtonsoft: Welches soll ich verwenden?

System.Text.Json wird fur neue .NET 8+-Projekte empfohlen. Es ist integriert, 2-5x schneller und unterstutzt AOT-Quellgeneratoren. Newtonsoft bleibt nutzlich fur bestehende Projekte und komplexe JObject-Szenarien.

C# Records oder traditionelle Klassen?

Records fur unveranderliche DTOs (C# 9+). Klassen fur Veranderlichkeit oder INotifyPropertyChanged. Fur ASP.NET Core sind Records die moderne Best Practice.

Wie gehe ich mit unbekannten JSON-Eigenschaften um?

System.Text.Json ignoriert sie standardmassig. Zum Auffangen verwenden Sie [JsonExtensionData]. Newtonsoft wirft standardmassig, konfigurieren Sie MissingMemberHandling.Ignore.

Die Konvertierung von JSON zu C# ist eine grundlegende Fahigkeit. Nutzen Sie unser kostenloses Tool fur sofortige Generierung.

Konvertieren Sie JSON sofort in C#-Klassen mit unserem kostenlosen Tool.

𝕏 Twitterin LinkedIn
War das hilfreich?

Bleiben Sie informiert

Wöchentliche Dev-Tipps und neue Tools.

Kein Spam. Jederzeit abbestellbar.

Verwandte Tools ausprobieren

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

Verwandte Artikel

JSON zu Java-Klasse Konverter: POJO, Jackson, Gson & Lombok Anleitung

JSON in Java-Klasse online konvertieren. POJO aus JSON mit Jackson, Gson und Lombok generieren mit Codebeispielen.

JSON zu TypeScript: VollstÀndiger Leitfaden mit Beispielen

Erfahren Sie, wie Sie JSON-Daten automatisch in TypeScript-Interfaces konvertieren. Verschachtelte Objekte, Arrays, optionale Felder und Best Practices.

JSON zu Kotlin Data Class: kotlinx.serialization, Moshi & Gson Anleitung

JSON in Kotlin Data Class online konvertieren. JSON-Parsing mit kotlinx.serialization, Moshi und Gson lernen.