Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
AOT-friendly serialization patterns for .NET applications. Covers System.Text.Json source generators for compile-time
serialization, Protocol Buffers (Protobuf) for efficient binary serialization, and MessagePack for high-performance
compact binary format. Includes performance tradeoff guidance for choosing the right serializer and warnings about
reflection-based serialization in AOT scenarios.
Scope
System.Text.Json source generators for compile-time serialization
Protocol Buffers (Protobuf) for binary serialization
MessagePack for high-performance compact format
Performance tradeoff guidance for serializer selection
AOT-safe serialization patterns and anti-patterns
Out of scope
Source generator authoring patterns -- see [skill:dotnet-csharp-source-generators]
HTTP client factory and resilience pipelines -- see [skill:dotnet-http-client] and [skill:dotnet-resilience]
Native AOT architecture and trimming -- see [skill:dotnet-native-aot] and [skill:dotnet-trimming]
Cross-references: [skill:dotnet-csharp-source-generators] for understanding how STJ source generators work under the
hood. See [skill:dotnet-integration-testing] for testing serialization round-trip correctness.
Serialization Format Comparison
Format
Library
AOT-Safe
Human-Readable
Relative Size
Relative Speed
Best For
JSON
System.Text.Json (source gen)
Yes
Yes
Largest
Good
APIs, config, web clients
Protobuf
Google.Protobuf
Yes
No
Smallest
Fastest
Service-to-service, gRPC wire format
MessagePack
MessagePack-CSharp
Yes (with AOT resolver)
No
Small
Fast
High-throughput caching, real-time
JSON
Newtonsoft.Json
No (reflection)
Yes
Largest
Slower
Legacy only -- do not use for AOT
When to Choose What
System.Text.Json with source generators: Default choice for APIs, configuration, and any scenario where
human-readable output or web client consumption matters. AOT-safe when using source generators.
Protobuf: Default wire format for gRPC. Best throughput and smallest payload size for service-to-service
communication. Schema-first development with .proto files.
MessagePack: When you need binary compactness without .proto schema management. Good for caching layers,
real-time messaging, and high-throughput scenarios where schema evolution is managed via attributes.
System.Text.Json Source Generators
System.Text.Json source generators produce compile-time serialization code, eliminating runtime reflection. This is
required for Native AOT and strongly recommended for all new projects. See [skill:dotnet-csharp-source-generators]
for the underlying incremental generator mechanics.
Basic Setup
Define a JsonSerializerContext with [JsonSerializable] attributes for each type you serialize:
using System.Text.Json.Serialization;
[JsonSerializable(typeof(Order))]
[JsonSerializable(typeof(List<Order>))]
[JsonSerializable(typeof(OrderStatus))]
publicpartialclassAppJsonContext : JsonSerializerContext
{
}
```json
### Using the Generated Context
```csharp
// Serializestring json = JsonSerializer.Serialize(order, AppJsonContext.Default.Order);
// Deserialize
Order? result = JsonSerializer.Deserialize(json, AppJsonContext.Default.Order);
// With options (created once, reused)var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
TypeInfoResolver = AppJsonContext.Default
};
string json = JsonSerializer.Serialize(order, options);
```json
### ASP.NET Core Integration
Register the source-generated context so Minimal APIs use it automatically. Note that `ConfigureHttpJsonOptions` applies to Minimal APIs only -- MVC controllers require separate configuration via `AddJsonOptions`:
```csharp
var builder = WebApplication.CreateBuilder(args);
// Minimal APIs: ConfigureHttpJsonOptions
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
});
// MVC Controllers: AddJsonOptions (if using controllers)
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
});
var app = builder.Build();
// Minimal API endpoints automatically use the registered context
app.MapGet("/orders/{id}", async (int id, OrderService service) =>
{
var order = await service.GetAsync(id);
return order ? Results.Ok(order) : Results.NotFound();
});
app.MapPost(, (Order order, OrderService service) =>
{
service.CreateAsync(order);
Results.Created(, order);
});
```text
;
});
```json
```csharp
[]
[]
[]
:
{
}
```json
```csharp
[]
[]
[]
{
Amount { ; ; }
Currency { ; ; } = ;
}
:
{
Last4Digits { ; ; } = ;
}
[]
:
{
}
```json
---
Protocol Buffers provide schema-first binary serialization. Protobuf the wire format gRPC AOT-safe.
```xml
<PackageReference Include= Version= />
<PackageReference Include= Version= PrivateAssets= />
```xml
```protobuf
syntax = ;
import ;
option csharp_namespace = ;
message OrderMessage {
int32 id = ;
customer_id = ;
repeated OrderItemMessage items = ;
google.protobuf.Timestamp created_at = ;
}
message OrderItemMessage {
product_id = ;
int32 quantity = ;
unit_price = ;
}
```text
Use Protobuf binary serialization without gRPC you need compact payloads caching, messaging, storage:
```csharp
Google.Protobuf;
[] bytes = order.ToByteArray();
restored = OrderMessage.Parser.ParseFrom(bytes);
stream = File.OpenWrite();
order.WriteTo(stream);
```text
```xml
<ItemGroup>
<Protobuf Include= GrpcServices= />
</ItemGroup>
```xml
---
MessagePack-CSharp provides high-performance binary serialization smaller payloads than JSON good .NET integration.
```xml
<PackageReference Include= Version= />
<!-- For AOT support -->
<PackageReference Include= Version= />
```xml
```csharp
MessagePack;
[]
{
[]
Id { ; ; }
[]
CustomerId { ; ; } = ;
[]
List<OrderItem> Items { ; ; } = [];
[]
DateTimeOffset CreatedAt { ; ; }
}
```text
```csharp
[] bytes = MessagePackSerializer.Serialize(order);
restored = MessagePackSerializer.Deserialize<Order>(bytes);
lz4Options = MessagePackSerializerOptions.Standard.WithCompression(
MessagePackCompression.Lz4BlockArray);
[] compressed = MessagePackSerializer.Serialize(order, lz4Options);
```text
For Native AOT compatibility, use the MessagePack source generator to produce a resolver:
```csharp
MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard
.WithResolver(GeneratedResolver.Instance);
```text
---
**Do use reflection-based serializers Native AOT trimming scenarios.** Reflection-based serialization fails at runtime the linker removes type metadata.
Newtonsoft.Json (`JsonConvert.SerializeObject` / `JsonConvert.DeserializeObject`) relies heavily runtime reflection. It **incompatible** Native AOT trimming:
```csharp
json = JsonConvert.SerializeObject(order);
order = JsonConvert.DeserializeObject<Order>(json);
json = JsonSerializer.Serialize(order, AppJsonContext.Default.Order);
order = JsonSerializer.Deserialize(json, AppJsonContext.Default.Order);
```json
Even System.Text.Json falls back to reflection without a source-generated context:
```csharp
json = JsonSerializer.Serialize(order);
json = JsonSerializer.Serialize(order, AppJsonContext.Default.Order);
```json
Replace `JsonConvert.SerializeObject` / `DeserializeObject` `JsonSerializer.Serialize` / `Deserialize`
Replace `[JsonProperty]` `[JsonPropertyName]`
Replace `JsonConverter` `<>`
4. `` `[]`
5. `` / `` `` / `` -
6. - --
---
##
### ()
| | (/) | (/) | |
|--------|--------------------|-----------------------|-------------|
| | | | |
| | | | |
| | | | () |
| | | | () |
| | | | () |
###
- ** ``** -- ; create once reuse
- **Use `JsonSerializerContext`** -- eliminates warm-up cost reduces allocation
- **Use `Utf8JsonWriter` / `Utf8JsonReader`** streaming scenarios you process JSON without full materialization
- **Use Protobuf `ByteString`** binary data instead of base64-encoded strings JSON
- **Enable MessagePack LZ4 compression** large payloads over the wire
---
- **Default to System.Text.Json source generators** all JSON serialization -- it AOT-safe, fast, built the framework
- **Use Protobuf service-to-service binary serialization** -- especially the wire format gRPC
- **Use MessagePack high-throughput caching real-time** -- binary compactness matters but `.proto` schema management unwanted
- **Never use Newtonsoft.Json AOT-targeted projects** -- it reflection-based incompatible trimming
- **Always register `JsonSerializerContext` ASP.NET Core** -- use `ConfigureHttpJsonOptions` Minimal APIs `AddJsonOptions` ; MessagePack requires `[MessagePackObject]`
See [skill:dotnet-native-aot] comprehensive AOT compilation pipeline, [skill:dotnet-aot-architecture] AOT-first design patterns, [skill:dotnet-trimming] trimming strategies ILLink descriptor configuration.
---
**Do use `JsonSerializer.Serialize(obj)` without a context AOT projects** -- it falls back to reflection fails at runtime. Always pass the source-generated `TypeInfo`.
**Do forget to list collection types `[JsonSerializable]`** -- `[JsonSerializable((Order))]` does cover `List<Order>`. Add `[JsonSerializable((List<Order>))]` separately.
**Do use Newtonsoft.Json `[JsonProperty]` attributes System.Text.Json** -- they are silently ignored. Use `[JsonPropertyName]` instead.
**Do mix MessagePack `[Key]` integer keys `[Key]` keys** the same type hierarchy -- pick one strategy stay consistent.
**Do omit `GrpcServices` attribute `<Protobuf>` items** -- without it, both client server stubs are generated, which may cause build errors you only need one.
---
- [System.Text.Json source generation](https:
- [Migrate Newtonsoft.Json to System.Text.Json](https:
- [Protocol Buffers .NET](https:
- [MessagePack-CSharp](https:
- [Native AOT deployment](https:
is
not
null
"/orders"
async
await
return
$"/orders/{order.Id}"
### Combining Multiple Contexts
When your application has multiple serialization contexts (e.g., different bounded contexts or libraries):
```csharp
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine(
AppJsonContext.Default,
CatalogJsonContext.Default,
InventoryJsonContext.Default
)
for MVC controllers (they are separate registrations)
- **Annotate all serialized types** -- STJ source generators only generate code for types listed in `[JsonSerializable]`