【问题标题】:Using 'UseMvc' to configure MVC is not supported while using Endpoint Routing使用端点路由时不支持使用“UseMvc”配置 MVC
【发布时间】: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() 函数。

【问题讨论】:

标签: c# asp.net-mvc asp.net-core .net-core


【解决方案1】:

我在以下官方文档“Migrate from ASP.NET Core 2.2 to 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. 禁用端点路由。正如异常消息所暗示的以及文档的以下部分中所述: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!");
                                });
                            });
                

                【讨论】:

                • 如果您解释一下如何此代码解决问题会有所帮助。
                • 仅仅发布代码是不够的。请解释此代码将回答问题的内容/原因/方式。
                • 这只是开箱即用的样板,实际上并不能帮助用户了解他们是什么
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-07-13
                • 2014-05-11
                • 1970-01-01
                • 1970-01-01
                • 2012-12-12
                • 2010-12-23
                • 1970-01-01
                相关资源
                最近更新 更多