Używanie „UseMvc” do konfigurowania MVC nie jest obsługiwane podczas korzystania z routingu punktów końcowych

120

Miałem projekt Asp.Net core 2.2.

Niedawno zmieniłem wersję z .net core 2.2 na .net core 3.0 Preview 8. Po tej zmianie widzę ten komunikat ostrzegawczy:

używanie „UseMvc” do konfigurowania MVC nie jest obsługiwane podczas korzystania z routingu punktów końcowych. Aby kontynuować korzystanie z „UseMvc”, ustaw „MvcOptions.EnableEndpointRouting = false” w „ConfigureServices”.

Rozumiem, że ustawiając wartość EnableEndpointRoutingfalse, mogę rozwiązać problem, ale muszę wiedzieć, jaki jest właściwy sposób rozwiązania tego problemu i dlaczego Endpoint Routing nie potrzebuje UseMvc()funkcji.

Mehrdad Babaki
źródło
2
o właściwym sposobie: w tym dokumencie docs.microsoft.com/en-us/aspnet/core/migration/… stwierdza się: „migracja aplikacji do Endpoint Routing, jeśli to możliwe”
dvitel

Odpowiedzi:

23

ale muszę wiedzieć, jaki jest właściwy sposób rozwiązania tego problemu

Ogólnie rzecz biorąc, należy użyć EnableEndpointRoutingzamiast UseMvci można zapoznać się z kodem uruchamiania aktualizacji routingu, aby uzyskać szczegółowe instrukcje włączania EnableEndpointRouting.

dlaczego Endpoint Routing nie potrzebuje funkcji UseMvc ().

Ponieważ UseMvcużywa the IRouter-based logici EnableEndpointRoutingużywa endpoint-based logic. Kierują się inną logiką, którą można znaleźć poniżej:

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

W przypadku EnableEndpointRoutingużywa EndpointMiddleware do kierowania żądania do punktów końcowych.

Edward
źródło
123

Rozwiązanie znalazłem w następującej oficjalnej dokumentacji „ Migrate from ASP.NET Core 2.2 to 3.0 ”:

Istnieją 3 podejścia:

  1. Zastąp UseMvc lub UseSignalR UseEndpoints.

W moim przypadku wynik wyglądał tak

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

    }
}

LUB
2. Użyj AddControllers () i 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();
        });

    }
}

LUB
3. Wyłącz routing punktów końcowych. Jak sugeruje komunikat o wyjątku i jak wspomniano w następnej sekcji dokumentacji: użyj mvc bez routingu punktów końcowych


services.AddMvc(options => options.EnableEndpointRouting = false);
//OR
services.AddControllers(options => options.EnableEndpointRouting = false);
Sergii Żurawskij
źródło
2
Działa to w asp.net core 3.0 i mogę łatwo korzystać z tego interfejsu API sieci Web dodawania
Tony Dong
1
Zaleca się (na tej stronie) użycie services.AddRazorPages();zamiastservices.AddMvc();
BurnsBA
1
Jest to dobre rozwiązanie, jeśli przechodzisz przez pierwszy samouczek dotyczący MVC i aktualizujesz z core2.1 do core3.0. To natychmiast rozwiązało mój problem, dzięki!
Spencer Pollock
opcja 3 działała świetnie dla mnie przy tworzeniu strony z nagimi kościami
Vic
50

To zadziałało dla mnie (dodaj Startup.csmetodę> ConfigureServices):

services.AddMvc (opcja => opcja.EnableEndpointRouting = fałsz)
Bonaventura72
źródło
2
Prosta odpowiedź, ale świetna odpowiedź!
noobprogrammer
3

Problem, który uważam za spowodowany aktualizacjami platformy .NET Core. Najnowsza wydana wersja platformy .NET Core 3.0 wymaga jawnej zgody na korzystanie z MVC.

Ten problem jest najbardziej widoczny, gdy próbuje się przeprowadzić migrację ze starszej wersji .NET Core (2.2 lub wersja zapoznawcza 3.0) do .NET Core 3.0

W przypadku migracji z wersji 2.2 do 3.0 użyj poniższego kodu, aby rozwiązać problem.

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

Jeśli używasz szablonu .NET Core 3.0,

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

ConfigServices po poprawce jak poniżej,

wprowadź opis obrazu tutaj

Dziękuję Ci

Akash Limbani
źródło
2

W przypadku DotNet Core 3.1

Użyj poniżej

Plik: Startup.cs public void Configure (aplikacja IApplicationBuilder, środowisko IHostingEnvironment) {

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

        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication();
        app.UseHttpsRedirection();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
sagar charde
źródło
Co zrobić ze wszystkimi wierszami konfiguracji usług?
Fanchi
0

Możesz użyć: w metodzie ConfigureServices:

services.AddControllersWithViews();

A dla metody konfiguracji:

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

To działało dla mnie na .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
źródło
-4

Użyj poniższego kodu

app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
Mandy
źródło
Pomogłoby, gdybyś wyjaśnił, jak ten kod rozwiązuje problem.
Robert Columbia
Sam kod pocztowy nie jest wystarczającą odpowiedzią. Proszę wyjaśnić, co / dlaczego / jak ten kod odpowie na pytanie.
nurdyguy
to tylko płyta kotłowa, która wychodzi z pudełka i faktycznie nie pomaga użytkownikowi w tym, że jest zły
Simon Price