O uso de 'UseMvc' para configurar MVC não é suportado ao usar o Endpoint Routing

119

Eu tinha um projeto Asp.Net core 2.2.

Recentemente, mudei a versão de .net core 2.2 para .net core 3.0 Preview 8. Após essa mudança, vejo esta mensagem de aviso:

o uso de 'UseMvc' para configurar o MVC não é suportado ao usar o Endpoint Routing. Para continuar usando 'UseMvc', defina 'MvcOptions.EnableEndpointRouting = false' dentro de 'ConfigureServices'.

Eu entendo que, ao definir EnableEndpointRoutingcomo false, posso resolver o problema, mas preciso saber qual é a maneira adequada de resolvê-lo e por que o Endpoint Routing não precisa UseMvc()funcionar.

Mehrdad Babaki
fonte
2
sobre a maneira adequada: este documento docs.microsoft.com/en-us/aspnet/core/migration/… declara "migre o aplicativo para Endpoint Routing, se possível"
dvitel

Respostas:

23

mas preciso saber qual é a maneira correta de resolver isso

Em geral, você deve usar em EnableEndpointRoutingvez de UseMvce pode consultar Atualizar código de inicialização de roteamento para obter etapas detalhadas a serem ativadas EnableEndpointRouting.

porque o Endpoint Routing não precisa da função UseMvc ().

Pois UseMvc, ele usa the IRouter-based logice EnableEndpointRoutingusa endpoint-based logic. Eles seguem lógicas diferentes que podem ser encontradas abaixo:

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());
}

Pois EnableEndpointRouting, ele usa EndpointMiddleware para rotear a solicitação para os terminais.

Edward
fonte
121

Encontrei a solução na seguinte documentação oficial " Migrar do ASP.NET Core 2.2 para 3.0 ":

Existem 3 abordagens:

  1. Substitua UseMvc ou UseSignalR por UseEndpoints.

No meu caso, o resultado ficou assim

  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}");
        });

    }
}

OU
2. Use AddControllers () e 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();
        });

    }
}

OU
3. Desative o roteamento de endpoint. Como a mensagem de exceção sugere e conforme mencionado na seguinte seção da documentação: use mvcwithout endpoint routing


services.AddMvc(options => options.EnableEndpointRouting = false);
//OR
services.AddControllers(options => options.EnableEndpointRouting = false);
Sergii Zhuravskyi
fonte
2
Isso funciona no asp.net core 3.0 e posso usar essa API de adição da web facilmente
Tony Dong
1
É recomendado (nessa página) usar em services.AddRazorPages();vez deservices.AddMvc();
BurnsBA
1
Esta é uma boa solução se você estiver passando pelo primeiro tutorial do mvc e atualizar do core2.1 para o core3.0. Isso resolveu meu problema imediatamente, obrigado!
Spencer Pollock de
a opção 3 funcionou muito bem para mim na construção de uma página
básica
50

Isso funcionou para mim (adicionar Startup.csmétodo> ConfigureServices):

services.AddMvc (option => option.EnableEndpointRouting = false)
Bonaventura72
fonte
2
Resposta simples, mas ótima resposta!
noobprogrammer
DIGA COMO ESTE CÓDIGO RESOLVE, não me importo com a solução, já sabia, quero saber o PORQUÊ e o COMO ...
Amir Hossein Ahmadi
3

O problema que descobri ser devido a atualizações na estrutura do .NET Core. A versão mais recente do .NET Core 3.0 lançada requer permissão explícita para usar MVC.

Esse problema é mais visível quando se tenta migrar do .NET Core mais antigo (versão 2.2 ou versão prévia 3.0) para o .NET Core 3.0

Se estiver migrando do 2.2 para o 3.0, use o código abaixo para corrigir o problema.

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

Se estiver usando o modelo .NET Core 3.0,

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

Método ConfigServices após a correção conforme abaixo,

insira a descrição da imagem aqui

Obrigado

Akash Limbani
fonte
2

Para DotNet Core 3.1

Use abaixo

Arquivo: Startup.cs public void Configure (IApplicationBuilder app, IHostingEnvironment env) {

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

        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication();
        app.UseHttpsRedirection();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
sagar charde
fonte
O que fazer com todas as linhas de configuração de serviços?
Fanchi
0

Você pode usar: no método ConfigureServices:

services.AddControllersWithViews();

E para o método Configure:

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

Isso funcionou para mim no .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();
    });
}
vivek nuna
fonte
-4

Use Abaixo do Código

app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
Mandy
fonte
Ajudaria se você explicasse como esse código resolve o problema.
Robert Columbia,
Simplesmente postar o código não é uma resposta suficiente. Explique o que / por que / como este código responderá à pergunta.
nurdyguy
isso é apenas um boiler plate que sai da caixa e não ajuda realmente o usuário com o que é adicionado
Simon Price