Использование UseMvc для настройки MVC не поддерживается при использовании маршрутизации конечных точек


122

У меня был проект ядра 2.2 Asp.Net.

Недавно я изменил версию с .net core 2.2 на .net core 3.0 Preview 8. После этого изменения я вижу это предупреждающее сообщение:

Использование UseMvc для настройки MVC не поддерживается при использовании маршрутизации конечных точек. Чтобы продолжить использование UseMvc, установите MvcOptions.EnableEndpointRouting = false внутри ConfigureServices.

Я понимаю, что установив EnableEndpointRoutingзначение false, я могу решить проблему, но мне нужно знать, как правильно ее решить и почему для маршрутизации конечных точек не нужна UseMvc()функция.


2
о правильном способе: в этом документе docs.microsoft.com/en-us/aspnet/core/migration/… говорится «перенесите приложение на маршрутизацию конечных точек, если возможно»
двитель

Ответы:


23

но мне нужно знать, как правильно ее решить

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

почему для маршрутизации конечных точек не требуется функция UseMvc ().

Ибо UseMvcон использует the IRouter-based logicи EnableEndpointRoutingиспользует endpoint-based logic. Они следуют другой логике, которую можно найти ниже:

if (options.Value.EnableEndpointRouting)
{
    var mvcEndpointDataSource = app.ApplicationServices
        .GetRequiredService<IEnumerable<EndpointDataSource>>()
        .OfType<MvcEndpointDataSource>()
        .First();
    var parameterPolicyFactory = app.ApplicationServices
        .GetRequiredService<ParameterPolicyFactory>();

    var endpointRouteBuilder = new EndpointRouteBuilder(app);

    configureRoutes(endpointRouteBuilder);

    foreach (var router in endpointRouteBuilder.Routes)
    {
        // Only accept Microsoft.AspNetCore.Routing.Route when converting to endpoint
        // Sub-types could have additional customization that we can't knowingly convert
        if (router is Route route && router.GetType() == typeof(Route))
        {
            var endpointInfo = new MvcEndpointInfo(
                route.Name,
                route.RouteTemplate,
                route.Defaults,
                route.Constraints.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value),
                route.DataTokens,
                parameterPolicyFactory);

            mvcEndpointDataSource.ConventionalEndpointInfos.Add(endpointInfo);
        }
        else
        {
            throw new InvalidOperationException($"Cannot use '{router.GetType().FullName}' with Endpoint Routing.");
        }
    }

    if (!app.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _))
    {
        // Matching middleware has not been registered yet
        // For back-compat register middleware so an endpoint is matched and then immediately used
        app.UseEndpointRouting();
    }

    return app.UseEndpoint();
}
else
{
    var routes = new RouteBuilder(app)
    {
        DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
    };

    configureRoutes(routes);

    routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));

    return app.UseRouter(routes.Build());
}

Для маршрутизации запроса к конечным точкам EnableEndpointRoutingон использует EndpointMiddleware .


129

Я нашел решение в следующей официальной документации « Переход с ASP.NET Core 2.2 на 3.0 »:

Есть 3 подхода:

  1. Замените UseMvc или UseSignalR на UseEndpoints.

В моем случае результат выглядел так

  public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        //Old Way
        services.AddMvc();
        // New Ways
        //services.AddRazorPages();
    }


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseStaticFiles();
        app.UseRouting();
        app.UseCors();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
        });

    }
}

ИЛИ
2. Используйте AddControllers () и UseEndpoints ()

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    }


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseStaticFiles();
        app.UseRouting();
        app.UseCors();

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

    }
}

ИЛИ
3. Отключить маршрутизацию конечных точек. Как следует из сообщения об исключении и как указано в следующем разделе документации: используйте mvc без маршрутизации конечных точек


services.AddMvc(options => options.EnableEndpointRouting = false);
//OR
services.AddControllers(options => options.EnableEndpointRouting = false);

2
Это работает в asp.net core 3.0, и я могу легко использовать этот добавленный веб-API
Тони Донг

1
Рекомендуется (на этой странице) использовать services.AddRazorPages();вместоservices.AddMvc();
BurnsBA

1
Это хорошее решение, если вы проходите через первое руководство по mvc и обновляетесь с core2.1 до core3.0. Это сразу решило мою проблему, спасибо!
Спенсер Поллок

вариант 3 отлично сработал для меня при создании простой страницы
Вик

51

Это сработало для меня (добавьте Startup.cs> метод ConfigureServices):

services.AddMvc (option => option.EnableEndpointRouting = false)

2
Простой ответ, но отличный ответ!
noobprogrammer

3

Я обнаружил, что проблема связана с обновлениями платформы .NET Core. Последняя выпущенная версия .NET Core 3.0 требует явного согласия на использование MVC.

Эта проблема наиболее заметна при попытке перейти со старой версии .NET Core (2.2 или предварительная версия 3.0) на .NET Core 3.0.

При переходе с 2.2 на 3.0 используйте приведенный ниже код для устранения проблемы.

services.AddMvc(options => options.EnableEndpointRouting = false);

Если вы используете шаблон .NET Core 3.0,

services.AddControllers(options => options.EnableEndpointRouting = false);

ConfigServices после исправления, как показано ниже,

введите описание изображения здесь

Спасибо


2

Для DotNet Core 3.1

Используйте ниже

Файл: Startup.cs public void Configure (приложение IApplicationBuilder, IHostingEnvironment env) {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

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

Что делать со всеми строками конфигурации сервисов?
Fanchi

0

Вы можете использовать: в методе ConfigureServices:

services.AddControllersWithViews();

И для метода настройки:

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });

0

Это сработало для меня в .Net Core 3.1.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseAuthorization();

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

-4

Используйте код ниже

app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });

Было бы полезно, если бы вы объяснили, как этот код решает проблему.
Роберт Колумбия

Простого размещения кода недостаточно. Объясните, пожалуйста, что / почему / как этот код ответит на вопрос.
nurdyguy

это просто котелок, который выходит из коробки и на самом деле не помогает пользователю в этом,
Саймон Прайс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.