dotnet/runtime

Json source generation do not support custom JsonConverter on the key of a Dictionary

已關閉

#110,634 建立於 2024年12月12日

 (5 則留言) (1 個反應) (0 位負責人)C# (5,445 個分叉)batch import
area-System.Text.Jsonenhancementhelp wanted

倉庫指標

星標
 (17,886 顆星)
PR 合併指標
 (平均合併 12天 11小時) (30 天內合併 661 個 PR)

描述

Description

while deserialize Dictionary<string, int> with a custom StringJsonConverter which is used to convert null to empty string , it throws:

Unhandled exception. System.NotSupportedException: The type 'System.String' is not a supported dictionary key using converter of type 'StringJsonConverter'. Path: $.Pages['Chapter 1'] | LineNumber: 4 | BytePositionInLine: 20. ---> System.NotSupportedException: The type 'System.String' is not a supported dictionary key using converter of type 'StringJsonConverter'.

if i remove StringJsonConverter, it works fine.

the environment is

.NET SDK:
 Version:           8.0.404
 Commit:            7b190310f2
 Workload version:  8.0.400-manifests.996cfe54
 MSBuild version:   17.11.9+a69bbaaf5
 OS Name:     Windows
 OS Version:  10.0.19044
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.404\

the full code is here:

using System.Text.Json;
using System.Text.Json.Serialization;

var options = new JsonSerializerOptions() { TypeInfoResolver = MyJsonSerializerContext.Default };

// everything works fine if I remove the line below
options.Converters.Add(new StringJsonConverter());

var book = JsonSerializer.Deserialize<Book>(
    """
    {
        "Title": "Philosopher's Stone",
        "Author": "J.K.Rowling",
        "Pages": {
            "Chapter 1": 10,
            "Chapter 2": 20
        }
    }
    """, options);
Console.WriteLine(book!.Pages["Chapter 1"]);

public class Book
{
    public string Title { get; set; } = "";
    public string Author { get; set; } = "";
    public Dictionary<string, int> Pages { get; set; } = new Dictionary<string, int>();
}

/// <summary>
/// read and write null string as empty string
/// </summary>
public class StringJsonConverter : JsonConverter<string>
{
    public override bool HandleNull => true;

    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var s = reader.GetString();
        return s == null ? string.Empty : s.Trim();
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(string.IsNullOrEmpty(value) ? string.Empty : value);
    }
}

[JsonSerializable(typeof(Book))]
public partial class MyJsonSerializerContext : JsonSerializerContext;

Reproduction Steps

  1. create an empty console app
  2. copy the code to the program.cs
  3. run

Expected behavior

no exception throws

Actual behavior

throws System.NotSupportedException

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

貢獻者指南