BLOG · .NET · APIs

Speed up your .NET APIs with 6 System.Text.Json attributes

Illustration: the JsonIgnore attribute in a code window

Your .NET applications definitely use JSON. But many developers don't exploit the full potential of System.Text.Json.

With the right attributes, you can shrink response sizes, precisely control exposed data and gain significant performance.

1. [JsonPropertyName]

Renames a property in the JSON. Essential to follow an external convention (snake_case, camelCase...) or align your contract with a third-party API.

[JsonPropertyName("release_year")]
public int ReleaseYear { get; set; }

2. [JsonIgnore]

Excludes a field from serialization and deserialization. Good practice to avoid exposing sensitive data (password, token, internal amounts...) in JSON responses.

[JsonIgnore]
public string PasswordHash { get; set; }

3. [JsonIgnore(Condition = WhenWritingNull)]

Skips properties whose value is null. The result: lighter, more readable JSON, especially useful for REST APIs returning complex objects with many optional fields.

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? DeliveryComment { get; set; }

4. [JsonInclude]

Forces the inclusion of non-public properties (a private setter, for instance). Useful when working with encapsulated domain objects while still exposing some data on output.

[JsonInclude]
public string Reference { get; private set; }

5. [JsonConstructor]

Explicitly selects the constructor used during deserialization. Essential if your class has no parameterless constructor, or several overloads.

[JsonConstructor]
public Order(Guid id, decimal amount) { ... }

6. [JsonExtensionData]

Captures all unmapped JSON fields into a dictionary. This tolerates structure variations without crashing the app: handy for partially dynamic data or API evolutions.

[JsonExtensionData]
public Dictionary<string, JsonElement>? UnknownFields { get; set; }

Bonus: going further

Other useful attributes: JsonNumberHandling to read numbers from strings, JsonPolymorphic and JsonDerivedType for inheritance, JsonUnmappedMemberHandling for unknown properties. And performance-wise, source generation with JsonSerializable is really interesting: serialization is generated at compile time, no reflection.

Takeaway: these attributes improve your APIs without reworking your whole object structure. You keep control over the emitted and accepted format, limit side effects when models evolve, and optimize your exchanges.

This article comes from one of my LinkedIn posts (in French): join the discussion ↗