如何在asp.net core中启用转义JSON字符串解析?

问题描述 投票:0回答:1

当我使用转义的 JSON 字符串向端点发送请求时,它会抛出异常“JSON 值无法转换为 Test.TestClass 。路径:$ | LineNumber:0 | BytePositionInLine:90。 “”。如何在 ASP.NET 5 中启用转义 JSON 字符串解析? 我正在使用 System.Text.Json(v 6.0.1)。尝试更新到(v8)但没有成功。还尝试使用 AddNewtonsoftJson() 但仍然得到相同的结果。

创建自定义 JSON 转换器是可行的,但需要一个全局适用的解决方案。

我的请求的curl带有转义的JSON字符串。

curl --location 'https://localhost:8080/api/testEndpoint' \
--header 'charset: utf-8' \
--header 'Content-Type: application/json' \
--data '"{\"testId\":0,\"created\":\"2024-03-09T14:17:19.9837955Z\"}"'

模型类

public class TestClass 
{
  public int TestId {get;set;}
  public DateTime Created {get;set;}
}
asp.net-core model-binding system.text.json
1个回答
0
投票

问题是客户端对请求 JSON 进行了双重序列化。感谢@Panagiotis Kanavos 的指出。

但是,在客户端问题解决之前,我创建了一个自定义 JSON 转换器来临时处理该问题。并将其发布,因为它可能对其他人出于不同目的有用。

在下面的代码中,只需为端点 dtos 实现一个空白接口“IJSONStringDto”,转换器将处理正常的 JSON 解析和双序列化 JSON 解析。

    public class JSONStringConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        if (typeof(IJSONStringDto).IsAssignableFrom(typeToConvert))
        {
            return true;
        }

        return false;
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        JsonConverter converter = (JsonConverter)Activator.CreateInstance(
           typeof(JSONStringObjectConverter<>).MakeGenericType(
               new Type[] { typeToConvert }),
           BindingFlags.Instance | BindingFlags.Public,
           binder: null,
           args: new object[] { options },
           culture: null);

        return converter;
    }

    private class JSONStringObjectConverter<TJSONStringType> : JsonConverter<TJSONStringType> where TJSONStringType: IJSONStringDto
    {
        public JSONStringObjectConverter(JsonSerializerOptions options)
        {

        }

        public override TJSONStringType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.String)
            {
                return JsonSerializer.Deserialize<TJSONStringType>(reader.GetString());
            }

            using (var jsonDoc = JsonDocument.ParseValue(ref reader))
            {
                return JsonSerializer.Deserialize<TJSONStringType>(jsonDoc.RootElement.GetRawText());
            }
        }

        public override void Write(Utf8JsonWriter writer, TJSONStringType value, JsonSerializerOptions options)
        {
            throw new NotImplementedException();
        }
    }
}

然后注册转换器

.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JSONStringConverterFactory());
    
});
© www.soinside.com 2019 - 2024. All rights reserved.