使用端点路由时,不支持使用“ UseMvc”来配置MVC


119

我有一个Asp.Net core 2.2项目。

最近,我将版本从.net core 2.2更改为.net core 3.0 Preview8。更改之后,我看到以下警告消息:

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

我知道通过设置EnableEndpointRouting为false可以解决此问题,但是我需要知道什么是解决问题的正确方法,以及为什么端点路由不需要UseMvc()功能。


2
有关正确方法的信息:此 docs.microsoft.com/zh-cn/aspnet/core/migration/… 指出“如有可能,将应用程序迁移到Endpoint Routing”
dvitel

Answers:


23

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

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

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

对于UseMvc,它使用the IRouter-based logicEnableEndpointRouting使用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将请求路由到端点。


120

我在以下官方文档“ 从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中有效,我可以轻松使用此添加的Web API
Tony Dong,

1
建议(在该页面上)services.AddRazorPages();代替services.AddMvc();
BurnsBA '19

1
如果您正在阅读第一个mvc教程并将其从core2.1升级到core3.0,则这是一个很好的解决方案。这立即解决了我的问题,谢谢!
斯潘塞·波洛克

选项3对我建立裸露的页面非常
Vic

50

这为我工作(添加Startup.cs> ConfigureServices方法):

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

2
简单的答案,但是好的答案!
noobprogrammer

说出此代码解决方案的方式,我不在乎解决方案,我已经知道了,我想知道为什么以及如何...
Amir Hossein Ahmadi

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公共无效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

这只是开箱即用的样板,实际上并没有帮助用户确保它们的吸附力
Simon Price
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.