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

Posted

技术标签:

【中文标题】使用端点路由时不支持使用“UseMvc”配置 MVC【英文标题】:Using 'UseMvc' to configure MVC is not supported while using Endpoint Routing 【发布时间】:2020-01-01 04:34:42 【问题描述】:

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

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

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

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

【问题讨论】:

关于正确方法:此文档docs.microsoft.com/en-us/aspnet/core/migration/… 声明“如果可能,将应用程序迁移到端点路由” 【参考方案1】:

我在以下官方文档“Migrate from ASP.NET Core 2.2 to 3.0”中找到了解决方案:

有3种方法:

    将 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. 禁用端点路由。正如异常消息所暗示的以及文档的以下部分中所述:use mvcwithout endpoint routing


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

【讨论】:

这适用于 asp.net core 3.0,我可以轻松使用这个添加 Web API 建议(在该页面上)使用services.AddRazorPages(); 而不是services.AddMvc(); 如果您通过first mvc tutorial 并从core2.1 升级到core3.0,这是一个很好的解决方案。这立即解决了我的问题,谢谢! 选项 3 非常适合我构建一个简单的页面【参考方案2】:

这对我有用(添加 Startup.cs > ConfigureServices 方法):

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

【讨论】:

简单的答案,但很好的答案!【参考方案3】:

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

一般情况下,您应该使用EnableEndpointRouting 而不是UseMvc,您可以参考Update routing startup code 了解启用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 将请求路由到端点。

【讨论】:

【参考方案4】:

我发现这个问题是由于 .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方法如下,

谢谢

【讨论】:

【参考方案5】:

在 ASP.NET 5.0 上默认禁用端点路由

只需在启动时进行配置

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

这对我有用

【讨论】:

【参考方案6】:

您可以使用: 在 ConfigureServices 方法中:

services.AddControllersWithViews();

对于配置方法:

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

【讨论】:

【参考方案7】:
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

【讨论】:

【参考方案8】:

对于 DotNet Core 3.1

在下面使用

文件:Startup.cs 公共无效配置(IApplicationBuilder 应用程序,IHostingEnvironment env)

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

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

【讨论】:

如何处理所有的服务配置行?【参考方案9】:

-> 在 ConfigureServices 方法中 - Startup.cs

        //*****REGISTER Routing Service*****
        services.AddMvc();
        services.AddControllers(options => options.EnableEndpointRouting = false);

-> 在配置方法中 - Startup.cs

       //*****USE Routing***** 
        app.UseMvc(Route =>
            Route.MapRoute(
                name:"default",
                template: "Controller=Name/action=Name/id?"
            );
        );

【讨论】:

【参考方案10】:

这对我有用

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

【讨论】:

【参考方案11】:

使用下面的代码

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

【讨论】:

如果您解释一下如何此代码解决问题会有所帮助。 仅仅发布代码是不够的。请解释此代码将回答问题的内容/原因/方式。 这只是开箱即用的样板,实际上并不能帮助用户了解他们是什么

以上是关于使用端点路由时不支持使用“UseMvc”配置 MVC的主要内容,如果未能解决你的问题,请参考以下文章

csharp useMvc与默认路由,路由

从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

springCloud(14):使用Zuul构建微服务网关-路由端点与路由配置详解

关于asp.netCore3.0区域和路由配置

Asp.Net Core 入门—— 路由

为 http 和 https 端点配置带有路由 (global.asax) 的 WCF 4