当我使用转义的 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;}
}
问题是客户端对请求 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());
});