[API Proposal]: Add Support for JsonAlternativePropertyNameAttribute in System.Text.Json
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- csharp, json
- Domain
- backend-api-design
Research direction
The issue names no repository files, tests, or entry points. Start by reviewing System.Text.Json's existing JsonPropertyNameAttribute behavior and the open questions about precedence, multiple matches, polymorphism, and converters. Done would require an agreed API and behavior specification before implementation.
Written by the indexing model from the issue text.
Description
Background and motivation
Could not find a similar issue - please correct me if this is a duplicate.
Summary
It would be extremely useful to have a built-in JsonAlternativePropertyNameAttribute in System.Text.Json to handle scenarios where a property might have multiple valid names in the JSON payload. This feature would simplify handling backward compatibility, versioning, and schema evolution without requiring extensive custom converters or breaking changes.
Problem Statement
When deserializing JSON using System.Text.Json, there is currently no straightforward way to map multiple property names in the JSON payload to a single property in a .NET class. This is particularly challenging when dealing with:
- Typographical errors: When legacy systems or earlier versions of an API have properties with incorrect spellings (e.g.,
OccuredAtvs.OccurredAt). - Schema evolution: When properties are renamed in newer API versions, but backward compatibility must be maintained for older JSON payloads.
- Third-party integrations: When consuming JSON from external sources where property names may vary or use different conventions.
Currently, developers must write custom JsonConverter implementations to handle such scenarios. This can be verbose, error-prone, and cumbersome, especially when working with large models or frequent schema changes.
Benefits
- Simplified Code: Reduces the need for custom
JsonConverterimplementations to handle alternative property names. - Backward Compatibility: Makes it easier to maintain backward compatibility when property names evolve over time.
- Reduced Boilerplate: Eliminates repetitive code for handling common schema evolution scenarios.
- Improved Developer Experience: Aligns with the declarative and attribute-based design philosophy of
System.Text.Json.
Workarounds
Currently, developers must write custom JsonConverter implementations or preprocess JSON manually to handle such cases. While this works, it introduces unnecessary complexity and duplication, especially in larger projects or libraries.
Considerations
- How will multiple
JsonAlternativePropertyNameAttributevalues interact with each other or withJsonPropertyName? - Should deserialization prioritize
JsonPropertyNameover alternative names when multiple matches are found? - How will this work with existing features like polymorphic deserialization or converters?
API Proposal
Proposed Solution
Introduce a JsonAlternativePropertyNameAttribute to specify alternative names for a property during deserialization.
public class MyEvent
{
[JsonPropertyName("OccurredAt")]
[JsonAlternativePropertyName("OccuredAt")]
public DateTimeOffset OccurredAt { get; set; }
public string Name { get; set; }
}
With this attribute, the OccurredAt property would be deserialized correctly from JSON with either OccurredAt or OccuredAt as the property name.
API Usage
Expected Behavior:
Given the following JSON payloads:
{ "OccuredAt": "2025-01-01T12:00:00Z", "Name": "Event1" }
{ "OccurredAt": "2025-01-01T12:00:00Z", "Name": "Event2" }
Both should deserialize into the same object:
var myEvent = JsonSerializer.Deserialize<MyEvent>(json, options);
Console.WriteLine(myEvent.OccurredAt); // Outputs: 1/1/2025 12:00:00 PM
When serializing, the primary property name (JsonPropertyName) would be used, ensuring consistency:
var json = JsonSerializer.Serialize(myEvent);
Console.WriteLine(json);
// Outputs: { "OccurredAt": "2025-01-01T12:00:00Z", "Name": "Event1" }
Alternative Designs
No response
Risks
No response
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/runtime
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
area-System.Reflection blocking-clean-ci-optional Known Build Error os-mac-os-x untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
area-CodeGen-coreclr untriaged
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agentic-workflows untriaged
Difficulty 1/5 Under an hour Newbie friendliness 78/100
-
area-VM-meta-mono untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
Create parent directories only after the containment check in InstallHelper.TryExtractToDirectory Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PowerShell/PSResourceGet#2056 ·