如何在ASP.NET Core 2的C# WebApi中全局定义路由根名称?
实现全局路由前缀(基于csproj名称)
嘿,作为ASP.NET Core 2和C#新手,想要给团队的WebApi模板统一加全局路由前缀(用csproj名称),不用每个控制器手动重复写?这个需求太贴合团队协作场景了,我来给你一步步实现!
我们的核心目标是:让所有控制器的路由自动带上api/v1/{csproj名称}/前缀,比如你的WebStoreAbc.csproj对应最终路由api/v1/WebStoreAbc/products,下面是具体实现步骤:
1. 创建自定义路由约定类
路由约定是ASP.NET Core中全局配置路由规则的核心扩展点,我们可以通过实现IControllerModelConvention来给所有控制器批量添加统一前缀:
using Microsoft.AspNetCore.Mvc.ApplicationModels; using System.Reflection; public class GlobalRoutePrefixConvention : IControllerModelConvention { private readonly string _globalPrefix; // 构造函数传入全局前缀参数 public GlobalRoutePrefixConvention(string globalPrefix) { _globalPrefix = globalPrefix?.Trim('/') ?? string.Empty; } public void Apply(ControllerModel controller) { // 遍历控制器的所有路由选择器,给每个路由拼接全局前缀 foreach (var selector in controller.Selectors) { if (selector.AttributeRouteModel != null) { // 如果控制器已有自定义路由模板,在前面拼接全局前缀 selector.AttributeRouteModel = new AttributeRouteModel { Template = $"{_globalPrefix}/{selector.AttributeRouteModel.Template.Trim('/')}" }; } else { // 如果控制器没定义路由,默认使用「前缀+[controller]」的规则 selector.AttributeRouteModel = new AttributeRouteModel { Template = $"{_globalPrefix}/[controller]" }; } } } }
2. 在Startup.cs中注册约定并获取csproj名称
默认情况下,项目编译后的程序集名称和csproj名称一致,我们可以通过程序集信息获取csproj名称,再拼到全局路由前缀里,最后注册自定义约定:
using System.Reflection; using Microsoft.AspNetCore.Mvc; public class Startup { public void ConfigureServices(IServiceCollection services) { // 获取当前程序集名称(即csproj的名称) var projectName = Assembly.GetEntryAssembly().GetName().Name; // 组装全局路由前缀 var globalRoutePrefix = $"api/v1/{projectName}"; services.AddMvc(options => { // 添加我们的自定义路由约定 options.Conventions.Add(new GlobalRoutePrefixConvention(globalRoutePrefix)); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // 适配ASP.NET Core 2.x版本 } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); } }
3. 编写控制器(无需手动加前缀)
现在你的控制器只需要写具体的业务路由部分即可,全局前缀会自动拼接上去:
// 这里只需要写"products",最终路由会自动变成api/v1/WebStoreAbc/products [Route("products")] public class ProductsController : Controller { [HttpGet] public IActionResult GetAllProducts() { return Ok(new List<string> { "Product A", "Product B", "Product C" }); } [HttpGet("{id}")] public IActionResult GetProductById(int id) { return Ok($"Product {id}"); } }
额外小提示
- 如果你的csproj名称包含空格或特殊字符,可以在获取
projectName后做清洗处理,比如projectName = projectName.Replace(" ", "-"),确保路由是合法的URL路径。 - 如果某个控制器需要跳过全局前缀(特殊场景),可以在控制器的
[Route]属性里使用绝对路径(比如[Route("/api/custom/products")]),但建议尽量保持路由规则统一,方便团队协作。 - 测试时,用Swagger或Postman访问即可,比如项目名称是WebStoreAbc,获取产品的接口地址就是
GET https://localhost:{port}/api/v1/WebStoreAbc/products
内容的提问来源于stack exchange,提问作者R4F6
相关产品推荐
相关产品推荐

