Обычная маршрутизация в API ASP.NET Core

Проблема:

Я создаю приложение API с NET Core 3.1. Я бы не хотел устанавливать атрибут маршрута для каждого ApiControllers и Действия. Я пробовал много комбинаций за UseEndpoints, чтобы установить обычный маршрут, но у меня ничего не вышло.

С некоторой конфигурацией я не могу заставить работать Api, с некоторыми другими я получаю это исключение во время запуска:

InvalidOperationException: действие «ApiIsWorking» не имеет маршрута атрибута. Методы действий на контроллерах, аннотированных ApiControllerAttribute, должны быть маршрутизированы по атрибутам.

Как я могу настроить startup.cs на автоматическое сопоставление контроллеров с их именем класса и действиями с их именем метода?

Спасибо!

Какой-то код:

startup.cs

...
services.AddControllers()
...

app.UseHttpsRedirection()
   .UseRouting()
   .UseAuthentication()
   .UseEndpoints(endpoints => ?? )
   .UseCoreHttpContext()
   .UseServerConfiguration();

controller.cs

[ApiController]
public class BaseAPI : ControllerBase 
{
        [HttpGet]
        public string ApiIsWorking()
        {
            return "API is working!";
        }
}

Решение:

Как говорит Реза Агаей в решении, ошибка заключалась в добавлении атрибута ApiController. После того, как я его удалил, начинает работать команда UseEndpoints.

Моя ошибка заключалась в том, что я добавил атрибут, чтобы иметь возможность распознавать, какие классы должны быть доступны через API. В этом не было необходимости, потому что UseEndpoints отображает только классы, унаследованные от ControllerBase.

Предупреждение:

1) Обычная маршрутизация требует атрибута [FromBody] в параметрах действий.

2) Я выделяю ответ Зинова об обычных проблемах маршрутизации с Swashbuckle в .NET Core.


person Paolo Crociati    schedule 13.02.2020    source источник
comment
Чтобы иметь обычную маршрутизацию для ваших контроллеров и действий, вам необходимо удалить атрибут [ApiController] из контроллера и настроить маршрут в UseEndpoints.   -  person Reza Aghaei    schedule 16.02.2020


Ответы (4)


Чтобы иметь обычную маршрутизацию для ваших контроллеров и действий, вам необходимо удалить атрибут [ApiController] и атрибут [Route] из вашего контроллера и действий и настроить маршрут в UseEndpoints.

Это уже упоминалось в документация:

Атрибут [ApiController] делает обязательной маршрутизацию атрибутов.

Действия недоступны через обычные маршруты, определенные UseEndpoints, _ 6_ или _ 7_ в Startup.Configure.

Пример

Это рабочая настройка, которая у меня есть для запуска:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

И пример контроллера API:

public class ValuesController : ControllerBase
{
    // values/getall
    [HttpGet]
    public IEnumerable<string> GetAll()
    {
        return new string[] { "value1", "value2" };
    }

    // values/getitem/1
    [HttpGet]
    public string GetItem(int id)
    {
        return "value";
    }
}
person Reza Aghaei    schedule 16.02.2020

РЕДАКТИРОВАТЬ:

Я пытался настроить его на своей машине. Когда я удалил атрибут Route из контроллера, я получил ошибку ниже:

InvalidOperationException: действие «WebAPISample.Controllers.WeatherForecastController.Index (WebAPISample)» не имеет маршрута атрибута. Методы действий на контроллерах, помеченные атрибутом ApiControllerAttribute, должны иметь маршрутизацию по атрибутам.

В самом сообщении об ошибке говорится, что контроллеры API должны использовать маршрутизацию атрибутов.

Я знаю, что это не отвечает на ваш вопрос, но с API .NET Core 3 это не представляется возможным.

Из документации:

Атрибут [ApiController] делает обязательной маршрутизацию атрибутов. Например:

[Route("api/[controller]")] 
[ApiController] 
public class ValuesController : ControllerBase

Действия недоступны по обычным маршрутам, определенным UseMvc или UseMvcWithDefaultRoute в Startup.Configure.

Обратитесь к этому страница в MSDN.

person Manoj Choudhari    schedule 13.02.2020
comment
это кажется невозможным. → Возможно, удалите [ApiController] и [Route(...)]attribute из контроллера / действий и настройте маршрут в UseEndpoints. Взгляните, например, на этот пост. - person Reza Aghaei; 16.02.2020

Вы пробовали это?

app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

person Miro Hudak    schedule 13.02.2020
comment
Да, у меня возникло это исключение при запуске: System.InvalidOperationException: «Action ApiIsWorking» не имеет маршрута атрибута. Методы действий на контроллерах, аннотированных ApiControllerAttribute, должны быть перенаправлены по атрибутам. - person Paolo Crociati; 13.02.2020
comment
@Paolo Crociati, Ваша проблема исправлена. Вы можете поделиться своим кодом здесь. - person Joel Dharansingh; 23.02.2021

Вот мой совет, если вы собираетесь использовать обычную маршрутизацию с ядром .net. После того, как вы закончите реализацию API, вы собираетесь добавить к нему некоторую документацию. Обычно люди используют этот пакет Nuget Swashbuckle.AspNetCore, который реализует более поздний стандарт OpenAPI (Swagger). Но вот проблема, когда вы используете обычную маршрутизацию и хотите сгенерировать документацию с помощью этого инструмента.

если вы используете обычную маршрутизацию (в отличие от маршрутизации по атрибутам), любые контроллеры и действия на тех контроллерах, которые используют обычную маршрутизацию, не будут представлены в ApiExplorer, что означает, что Swashbuckle не сможет найти эти контроллеры и сгенерировать операции Swagger из их

Для получения дополнительной информации перейдите по этой ссылке: Swashbuckle Надеюсь, это спасет у вас много головной боли в будущем с документацией для вашего api

person Zinov    schedule 16.02.2020