Web API изменить парсер JSON - PullRequest
       47

Web API изменить парсер JSON

0 голосов
/ 15 января 2019

Я пытаюсь изменить анализатор JSON в своем проекте веб-API.

Я прошел следующие уроки:

https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-2.2

https://www.youtube.com/watch?v=tNzgXjqqIjI

https://weblog.west -wind.com / posts / 2012 / Mar / 09 / Использование альтернативного JSON-Serializer-in-ASPNET-Web-API

Iтеперь у меня есть следующий код:

public class MyJsonFormatter : MediaTypeFormatter
    {
        public MyJsonFormatter()
        {
            base.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
        {
            return null;
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            return null;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
        }

        public override bool CanReadType(Type type)
        {
            return true;
        }

        public override bool CanWriteType(Type type)
        {
            return true;
        }

        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            return base.GetPerRequestFormatterInstance(type, request, mediaType);
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return null;
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
        {
            return null;
        }

        public override IRequiredMemberSelector RequiredMemberSelector { get => base.RequiredMemberSelector; set => base.RequiredMemberSelector = value; }
    }   



public static void Register(HttpConfiguration config)
{
    ///Other stuff...
    GlobalConfiguration.Configuration.Formatters.Clear();
    GlobalConfiguration.Configuration.Formatters.Insert(0, new MyJsonFormatter());          
}

Моя проблема в том, что что бы я ни делал, JSON анализируется и кажется, что он игнорирует мой код - я могу генерировать исключения в методах чтения или записи, и ничего не произойдет, прерветсяочки не попадают в атаку и т. д.

Я знаю, что этот форматер добавляется, поскольку видны только типы контента в моем классе, и если я установлю CanReadType для возврата false, то ничего не будет проанализировано.

Мой вопрос: как я могу заставить код выполнять мои переопределения?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Обновить, как зарегистрировано форматтер

public static class WebApiConfig {

    public static void Register(HttpConfiguration config) {

        // Other stuff...

        var jsonFormatter = new MyJsonFormatter();
        config.Formatters.Clear();
        config.Formatters.Insert(0, jsonFormatter);

        //...
    }
}

Убедитесь, что предложенный синтаксис соблюдается при запуске или там, где когда-либо запускается приложение.

// configure Web Api
GlobalConfiguration.Configure(WebApiConfig.Register);

Существует также процесс согласования контента, как предлагается в следующей статье

Поддержка только JSON в ASP.NET Web API - правильный путь

Адаптируя его к вашему примеру, он будет выглядеть как

public class JsonContentNegotiator : IContentNegotiator {
    MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
    private readonly MyJsonFormatter _jsonFormatter;

    public JsonContentNegotiator(MyJsonFormatter formatter) {
        _jsonFormatter = formatter;
    }

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters) {
        var result = new ContentNegotiationResult(_jsonFormatter, mediaType);
        return result;
    }
}

И зарегистрирован против вашего HttpConfiguration

var jsonFormatter = new MyJsonFormatter();

config.Formatters.Clear();
config.Formatters.Insert(0, jsonFormatter);

//update content negotiation
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

Наконец, следует отметить, что фреймворк тесно связал свое JSON-форматирование с собственным JsonMediaTypeFormatter

/// <summary>
/// Gets the <see cref="MediaTypeFormatter"/> to use for Json.
/// </summary>
public JsonMediaTypeFormatter JsonFormatter
{
    get { return Items.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); }
}

Справочный источник

Таким образом, в зависимости от того, какая часть конвейера фактически зависит от существования экземпляра JsonMediaTypeFormatter, это, вероятно, повлияет на форматирование, связанное с JSON.

Если это действительно проблема, тогда я предлагаю взять из JsonMediaTypeFormatter и переопределить его членов по мере необходимости.

public class MyJsonFormatter : JsonMediaTypeFormatter {

    //... removed for brevity

}

Но это может повлечь за собой свои проблемы в зависимости от того, с чем связан этот базовый класс.

0 голосов
/ 17 января 2019

Вам необходимо зарегистрировать ваш форматтер в конфигурации при запуске.

...