Можете ли вы переопределить веб-API десериализации тела - PullRequest
0 голосов
/ 04 марта 2020

Когда я пытаюсь переопределить параметры сериализации для контроллера, они используются для создания ответа, но игнорируются при анализе тела.

Мне нужно переопределить параметры сериализации json для каждого запроса в WebAPI. Я пытаюсь изменить параметры сериализации в зависимости от используемого маршрута. Пример: если это API V1, используйте SerializationSettingsA, если это API V2, используйте SerializationSettingsB.

Я пробовал несколько подходов, включая переопределение IContentNegotiator и IHttpControllerActivator, надеясь установить параметры сериализации для контекста, но в любом случае это не работает. Поведение, которое я наблюдаю, заключается в том, что параметры переопределения сериализации используются при создании тела ответа, но не при разборе запроса. Существуют ли другие параметры, которые необходимо переопределить для изменения способа анализа тела запроса.

class PerControllerConfigActivator : IHttpControllerActivator
{
    private static readonly DefaultHttpControllerActivator Default = new DefaultHttpControllerActivator();

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        controllerDescriptor.Configuration = HttpConfigurationFactory.CreateDefaultConfiguration();
        controllerDescriptor.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Insert(0,
            new VersionedPropertyConverter(request.RequestUri.AbsoluteUri));

        var result = Default.Create(request, controllerDescriptor, controllerType);
        return result;
    }
}
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var configuration = new HttpConfiguration();
        configuration.MapHttpAttributeRoutes();
        configuration.Formatters.Clear();
        configuration.Services.Replace(typeof(IHttpControllerActivator), new PerControllerConfigActivator());
        app.UseWebApi(configuration);
    }
}

1 Ответ

0 голосов
/ 04 марта 2020

Заимствуя некоторые идеи из здесь , вы можете использовать настраиваемые средства форматирования ввода с указанным c заголовком типа содержимого для самого запроса.

Сначала необходимо создать средство форматирования ввода для переопределенной версии

public class MyNonDefaultJsonFormatter : InputFormatter
{
  public MyNonDefaultJsonFormatter()
  {
    this.SupportedMediaTypes.Clear()
    this.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/non-default-json");
  }

  public override bool CanRead(InputFormatterContext context)
  {
    return base.CanRead(context);
  }

  public override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext)
  {
    //Do some custom deserializing on context.HttpContext.Request.Body
  }
}

Затем необходимо зарегистрировать входной форматтер в службах конфигурации

services.AddMvc(options =>
{
  options.InputFormatters.Add(new MyNonDefaultJsonFormatter());
}

Затем укажите тип содержимого как "application / non-default- json "при выполнении запроса.

В качестве другой идеи вы можете удалить все десериализатор по умолчанию JSON и вместо этого зарегистрировать два собственных сериализатора, оба принимают стандартное приложение / json, но с проверка типов в переопределении CanReadType, которое позволяет дифференцировать. У меня не было шанса проверить это сам, но если я сделаю это, сообщу здесь.

...