我有一只Asp。Net core 2.2项目。

最近,我把。net core 2.2版本改成了。net core 3.0 Preview 8。在这个更改之后,我看到这个警告消息:

使用'UseMvc'配置MVC时,使用端点是不支持的 路由。要继续使用“UseMvc”,请设置 “MvcOptions。EnableEndpointRouting = false' inside 'ConfigureServices'。

我明白,通过设置EnableEndpointRouting为false,我可以解决这个问题,但我需要知道解决它的正确方法是什么,以及为什么端点路由不需要UseMvc()函数。


当前回答

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

这也适用于。net Core 5

其他回答

这对我来说是有效的(在Startup.cs > ConfigureServices方法中添加):

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

但我需要知道正确的解决方法是什么

通常,您应该使用EnableEndpointRouting而不是UseMvc,并且您可以参考更新路由启动代码以获得启用EnableEndpointRouting的详细步骤。

为什么端点路由不需要UseMvc()函数。

对于UseMvc,它使用基于irouter的逻辑,而EnableEndpointRouting使用基于端点的逻辑。他们遵循不同的逻辑,可以在下面找到:

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将请求路由到端点。

对于DotNet核心3.1

使用下面的

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

我在下面的官方文档中找到了解决方案。NET Core 2.2到3.0":

有3种方法:

用UseEndpoints替换UseMvc或UseSignalR。

在我的例子中,结果是这样的

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

端点路由在ASP上默认是禁用的。NET 5.0

只需在启动中配置

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options => options.EnableEndpointRouting = false);
    }
    

这对我很有效