Использование атрибута FormatFilter в API mvc core 2.1.3 - PullRequest
0 голосов
/ 29 октября 2018

Я сталкиваюсь с некоторыми трудностями при получении [FormatFilter] для работы в моем MVC Core 2.1.3 API Я хочу, чтобы моя конечная точка поддерживала JSON и XML, поэтому я написал этот код:

Startup класс, который наследуется от StartupCore класса:

public class Startup : StartupCore
{
    protected override void OnConfigure(
        IApplicationBuilder app,
        IHostingEnvironment env,
        ILoggerFactory loggerFactory,
        IApplicationLifetime appLifetime) => AutoMappings.Initialize();
}

И (частично) это StartupCore класс

//....
services
    .AddCors()
    .AddMvcCore()
    .AddApiExplorer()
    .AddJsonFormatters()
    .AddXmlSerializerFormatters() //With or without this line; no luck
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
    })
    .AddMvcOptions(options =>
    {
        options.InputFormatters.Add(new PlainTextInputFormatter());
        options.OutputFormatters.Add(new CsvOutputFormatter());
        options.FormatterMappings.SetMediaTypeMappingForFormat("csv", MediaTypeHeaderValue.Parse("text/csv"));
        options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
        options.FormatterMappings.SetMediaTypeMappingForFormat("xml", MediaTypeHeaderValue.Parse("application/xml"));
    })
//.......

Когда я использую атрибут FormatFilter на моем контроллере, как

[HttpGet]
[FormatFilter]
[Route("/public/feed/{format}")]
public async Task<IActionResult> CreateFeed(string format)
{
    //
}

Я получаю сообщение об ошибке: Autofac.Core.Registration.ComponentNotRegisteredException: запрошенная служба 'Microsoft.AspNetCore.Mvc.Formatters.FormatFilter' не была зарегистрирована.

Однако, когда я использую атрибут Produces, он дает мне данные XML.

[HttpGet]
[Produces("application/xml")]
[Route("/public/feed/{format}")]
public async Task<IActionResult> CreateFeed(string format)
{
    //
}

Я мог бы получить две конечные точки; один для JSON и один для XML, но у меня есть одна конечная точка с FormatFilter.

Так чего мне здесь не хватает?

ВОЗМОЖНОЕ РЕШЕНИЕ : сейчас я использую атрибут Produces [Produces("application/json", "application/xml"]

Используемый источник: https://andrewlock.net/formatting-response-data-as-xml-or-json-based-on-the-url-in-asp-net-core/

Ответы [ 3 ]

0 голосов
/ 06 ноября 2018

Если конечная точка или контроллер используют атрибут FormatFilter, то соответствующая служба должна быть зарегистрирована с помощью AddFormatterMappings:

services.AddMvcCore()
...
.AddFormatterMappings()
0 голосов
/ 14 июня 2019

У меня также была эта проблема с моим проектом .Net Core 2.1 WebAPI, и я обнаружил, что мне нужно явно установить заголовок запроса «Принять» как часть моего вызова Ajax. В моем исходном проекте .Net 4.7 Web API для свойства правильного типа содержимого было возвращено значение свойства dataType либо «json», либо «xml», но, по-видимому, не для .Net Core. Мой Ajax-вызов, как показано ниже:

$.ajax({
    type: 'GET',
    beforeSend: function (request)
    {
        request.setRequestHeader("Accept", "application/xml");
        // or for json request.setRequestHeader("Accept", "application/json");
    },
    traditional: true,
    url: uri,
    contentType: 'application/json; charset=utf-8',
    dataType: 'xml',
    // or for json dataType: 'json',
    success: function (data)
    {
        ...
    },
    error: function (req, status, err)
    {
        ...
    }
});

Мне также нужно было запретить кэширование, чтобы каждый раз в мой метод контроллера передавался правильный заголовок Accept, устанавливая свойство NoStore в декораторе ResponseCache:

    [ResponseCache(NoStore = true)]
    public ActionResult Get(string customerName)
    {
       ...
    }
0 голосов
/ 29 октября 2018

В вашем StartupCore вы полагаетесь на событие OnMvcCoreServiceConfiguration, чтобы добавить свой форматер вывода XML. Это сработает на линии, где вы звоните AddMvcCore. Затем, позже, вы снова позвоните AddMvcOptions, что переопределит предыдущий сделанный вами звонок. Во время второго вызова вы не добавляете средство форматирования XML, поэтому оно никогда не добавляется.

Вам нужно обратить внимание на асинхронный характер происходящего. Вы передаете действие, которое будет вызываться в какой-то момент при запуске приложения, поэтому при первом вызове AddMvcOptions на самом деле с этим ничего не происходит. Когда вы позже вызовете его снова, вы устанавливаете новое действие, которое оно в конечном итоге будет использовать, заменяя то, которое вы установили ранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...