У меня есть этот простой JsonFormatter:
public sealed class Int64StringConversionFormatter : IJsonFormatter<long> {
public void Serialize(ref JsonWriter writer, long value, IJsonFormatterResolver formatterResolver) {
writer.WriteString(value.ToString(NumberFormatInfo.InvariantInfo));
}
public long Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) {
var token = reader.GetCurrentJsonToken();
if (token == JsonToken.String) {
var s = reader.ReadString();
return
long.TryParse(s, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out var l)
? l
: 0;
}
if (token != JsonToken.Number)
throw new ValueProviderException("The provided value is not String or Int64.");
var value = reader.ReadInt64();
return value;
}
}
, который является реализацией Utf8Json.IJsonFormatter<>
для работы со значениями long
. Я добавил этот форматер в приложение AspNetCore WebApi следующим образом:
public static MvcOptions SetupCustomJsonFormatter(
this MvcOptions options) {
CompositeResolver.RegisterAndSetAsDefault(_formatters, _resolvers);
options.InputFormatters.Insert(0, new Utf8JsonInputFormatter());
options.OutputFormatters.Insert(0, new Utf8JsonOutputFormatter());
return options;
}
А вот мои _formatters
и _resolvers
:
static readonly IJsonFormatterResolver[] resolvers = {
StandardResolver.ExcludeNullCamelCase,
ImmutableCollectionResolver.Instance,
EnumResolver.Default,
DynamicGenericResolver.Instance,
};
static readonly IJsonFormatter[] _formatters
= new [] {new Int64StringConversionFormatter()};
Кроме того, вот мой Utf8JsonInputFormatter
:
internal sealed class Utf8JsonInputFormatter : IInputFormatter {
private readonly IJsonFormatterResolver _resolver;
public Utf8JsonInputFormatter() : this(null) {
}
public Utf8JsonInputFormatter(IJsonFormatterResolver resolver) {
_resolver = resolver ?? JsonSerializer.DefaultResolver;
}
public bool CanRead(InputFormatterContext context)
=> context.HttpContext.Request.ContentType?.StartsWith("application/json") == true;
public async Task<InputFormatterResult> ReadAsync(InputFormatterContext context) {
var request = context.HttpContext.Request;
if (request.Body.CanSeek && request.Body.Length == 0) return await InputFormatterResult.NoValueAsync();
var result = await JsonSerializer.NonGeneric.DeserializeAsync(context.ModelType, request.Body, _resolver);
return await InputFormatterResult.SuccessAsync(result);
}
}
Кажется, все должно быть в порядке. Но методы Int64StringConversionFormatter.Serialize
и Int64StringConversionFormatter.Deserializ
никогда не вызываются. Я проверил конфигурацию с другим простым форматером (скажем, UnixDateTimeFormatter
), и он работает просто отлично. Но я не могу понять, почему этого не зовут. Ты хоть представляешь, что мне здесь не хватает?