【问题标题】:Api Routing in .net core 3.0.net core 3.0 中的 API 路由
【发布时间】:2020-04-06 11:05:22
【问题描述】:

我是 .net 核心的新手,我想为我的 api 设置一个 MapRoute。 我在 startup.cs 中配置端点像

app.UseEndPoints(endpoints=>{
    endpoints.MapController("defaultApi","v1/{controller="cont"}/{action}/{id?}");
    endpoints.MapController("defaultNonActionApi","v1/{controller="cont"}/{id?}")l
    endpoints.MapHealthChecks("/healthz");
});

在controller.cs中

[ApiController]
[Route("[controller]")]
public class contController:ControllerBase{
    [HttpGet]
    public ActionResult Get(){}
}

useEndpoints 中的配置没有用,如果我转到 https://localhost:port/v1/cont 它会返回 404,如果我转到 https://localhost:port/cont 它可以返回预期结果。

似乎 RouteAttribute 覆盖了 useEndpoints 中的配置,但我无法删除 ApiController 的 RouteAttribute。

我知道将Route("[controller]") 更改为Route("v1/[controller]") 可以解决这个问题,但我想要的是可以在startup.cs 中配置的更全局的东西。 谢谢。

【问题讨论】:

    标签: asp.net-core-webapi asp.net-core-3.0


    【解决方案1】:

    这是一个简单的演示,如下所示:

    1.创建自定义MvcOptionsExtensions

    public static class MvcOptionsExtensions
    {
        public static void UseGeneralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
        {
            opts.Conventions.Add(new RoutePrefixConvention(routeAttribute));
        }
    
        public static void UseGeneralRoutePrefix(this MvcOptions opts, string prefix)
        {
            opts.UseGeneralRoutePrefix(new RouteAttribute(prefix));
        }
    }
    
    public class RoutePrefixConvention : IApplicationModelConvention
    {
        private readonly AttributeRouteModel _routePrefix;
    
        public RoutePrefixConvention(IRouteTemplateProvider route)
        {
            _routePrefix = new AttributeRouteModel(route);
        }
    
        public void Apply(ApplicationModel application)
        {
            foreach (var selector in application.Controllers.SelectMany(c => c.Selectors))
            {
                if (selector.AttributeRouteModel != null)
                {
                    selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_routePrefix, selector.AttributeRouteModel);
                }
                else
                {
                    selector.AttributeRouteModel = _routePrefix;
                }
            }
        }
    }
    

    2.在Startup.cs中注册:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews(o => { o.UseGeneralRoutePrefix("v1"); });
    }
    
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    

    3.控制器:

    [ApiController]
    [Route("[controller]")]
    public class contController:ControllerBase{
        [HttpGet]
        public ActionResult Get(){}
    }
    

    【讨论】:

    • 效果很好,谢谢。但是我有一个问题,如果我想在一个解决方案中同时设置 v1 和 v2,我应该如何配置这个前缀。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多