在 .NET WebAPI 中,路由配置是处理客户端请求时确定如何将请求映射到适当的控制器和操作方法的关键步骤。路由配置允许你定义 URL 模式,并决定哪个控制器或操作处理哪个请求。
以下是 .NET WebAPI 路由配置的详细介绍,包括其基本概念、配置方法和高级配置技巧。
1. WebAPI 路由的基本概念
ASP.NET Core WebAPI 使用路由来将 HTTP 请求映射到控制器的特定操作方法。路由是基于 URL 模式的,URL 模式定义了资源的路径结构。
路由定义通常由以下部分组成:
路由模板:定义 URL 结构的格式。
控制器:控制器是处理客户端请求的类。
操作方法:控制器中的方法,执行具体的处理逻辑。
2. 默认路由配置
在 ASP.NET Core WebAPI 中,路由通常通过 Startup.cs 文件中的 UseEndpoints 方法来配置。默认路由模式如下:
默认路由模板:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
默认情况下,ASP.NET Core WebAPI 使用"属性路由",它依赖于在控制器或操作方法上定义的路由属性:
示例:
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// GET: api/products
[HttpGet]
public IActionResult Get()
{
// 获取产品的逻辑
return Ok(products);
}
// GET: api/products/5
[HttpGet("{id}")]
public IActionResult Get(int id)
{
// 获取指定产品的逻辑
var product = products.SingleOrDefault(p => p.Id == id);
return Ok(product);
}
}
- [ApiController]:指明这是一个 WebAPI 控制器。
- [Route("api/[controller]")]:[controller] 将被替换为控制器名称,例如 ProductsController 将会被映射为 /api/products。
- [HttpGet]:指定该方法响应 HTTP GET 请求。
- [HttpGet("{id}")]:使用参数 {id} 作为 URL 路径中的变量。
3. 基于属性的路由
在 .NET WebAPI 中,基于属性的路由是一种主要的路由定义方式。通过将 [Route] 属性应用到控制器类或方法上来定义 URL 路径。
示例:
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
// GET api/orders
[HttpGet]
public IActionResult GetAllOrders()
{
return Ok("返回所有订单");
}
// GET api/orders/5
[HttpGet("{id}")]
public IActionResult GetOrderById(int id)
{
return Ok($"返回订单 {id}");
}
// POST api/orders
[HttpPost]
public IActionResult CreateOrder(Order order)
{
// 创建订单逻辑
return CreatedAtAction(nameof(GetOrderById), new { id = order.Id }, order);
}
}
基于属性的路由优势:
更加灵活,能为每个控制器或操作方法自定义路由。
方便处理多种HTTP方法,如 GET、POST、PUT 和 DELETE。
4. Route Template Parameters(路由模板参数)
路由模板参数允许动态地从 URL 提取值。它们定义在花括号 {} 中。
示例:
[HttpGet("{category}/{id}")]
public IActionResult GetProductByCategoryAndId(string category, int id)
{
// 根据category和id返回产品
return Ok($"Category: {category}, ID: {id}");
}
这里的 {category} 和 {id} 是路由模板参数,分别将 URL 中的值绑定到操作方法的参数 category 和 id。
5. 路由约束(Route Constraints)
路由约束用于限制 URL 参数的类型或模式。例如,你可以通过路由约束确保 id 参数是一个整数。
示例:
[HttpGet("{id:int}")]
public IActionResult GetById(int id)
{
// 只有id是整数时才能匹配此路由
return Ok($"Product with ID: {id}");
}
常见的路由约束有:
- int:必须是整数。
- guid:必须是 GUID。
- bool:必须是布尔值。
- minlength(x):最小字符串长度为 x。
6. 默认值(Default Values)
你可以为路由参数定义默认值,避免在请求中没有提供参数时引发错误。
示例:
[HttpGet("{id:int?}")]
public IActionResult GetById(int? id = null)
{
if (id.HasValue)
{
return Ok($"Product with ID: {id}");
}
return Ok("No ID provided");
}
这里,{id:int} 表示 id 是可选的,如果没有提供,默认值为 null。
7. 自定义路由前缀
你可以通过控制器的 RoutePrefix 属性为控制器统一设置路由前缀。
示例:
[Route("api/v1/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetAllProducts()
{
return Ok(products);
}
}
上面的代码中,api/v1/products 会被映射到 GetAllProducts 方法。
8. 区域路由(Areas Routing)
如果你的 WebAPI 项目较大,可以使用 区域(Areas) 来组织控制器。
示例:
[ApiController]
[Area("Admin")]
[Route("api/admin/[controller]")]
public class AdminProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetAdminProducts()
{
return Ok("Admin Products");
}
}
这里的 Area("Admin") 将路由配置到了 /api/admin 下。
9. 多路由匹配
你可以为一个操作方法设置多个路由。
示例:
[HttpGet]
[Route("products")]
[Route("items")]
public IActionResult GetProducts()
{
return Ok("Products or Items");
}
无论是 /products 还是 /items,都会被映射到 GetProducts 方法。
10. 高级路由配置(自定义中间件)
在一些特殊场景中,你可以通过自定义路由中间件来控制路由行为。
示例:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
11、配置默认路由
1. 在 Startup.cs 中配置默认路由
在 ASP.NET Core 中,路由通常在 Startup.cs 文件中的 UseEndpoints 方法中配置。你可以设置默认的控制器、操作方法和参数。
示例:
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 添加中间件配置代码...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// 设置默认路由
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
controller=Home:表示当没有指定控制器时,默认使用 HomeController。
action=Index:表示当没有指定操作方法时,默认使用 Index 方法。
id:表示 id 是一个可选参数。
在这个配置下,如果访问 http://localhost:5000/,默认会映射到 HomeController 的 Index 方法。
HomeController 示例:
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet]
public IActionResult Index()
{
return Ok("This is the default page!");
}
}
2. 配置多个默认路由
有时你可能需要为不同的部分定义多个默认路由。你可以在 UseEndpoints 方法中设置多个 MapControllerRoute。
示例:
app.UseEndpoints(endpoints =>
{
// 默认路由1
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
// 默认路由2
endpoints.MapControllerRoute(
name: "admin",
pattern: "admin/{controller=Admin}/{action=Dashboard}/{id?}");
});
默认路由1:映射 HomeController 到 /,默认使用 Index 方法。
默认路由2:映射到 /admin,将 AdminController 的 Dashboard 方法作为默认操作。
在这种配置下:
访问 http://localhost:5000/ 会进入 HomeController.Index()。
访问 http://localhost:5000/admin 会进入 AdminController.Dashboard()。
3. 使用属性路由设置默认 URL
除了在 Startup.cs 文件中配置全局路由,你还可以使用 属性路由 来定义默认路由。
示例:
[Route("")]
[Route("Home")]
public class HomeController : ControllerBase
{
[HttpGet("")]
[HttpGet("Index")]
public IActionResult Index()
{
return Ok("This is the default page with attribute routing!");
}
}
在这里,我们通过 [Route("")] 将控制器映射到根路径 /,通过 [HttpGet("")] 设置了默认操作方法。如果访问 http://localhost:5000/,会返回 Index 方法的结果。
12、静态文件配置默认路由
步骤1:启用静态文件支持
首先,确保你的 ASP.NET Core 项目支持静态文件。通常,你需要在 Startup.cs 文件中添加配置,启用静态文件服务。
修改 Startup.cs 文件:
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 启用开发模式下的详细错误页面(可选)
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 启用静态文件中间件
app.UseStaticFiles();
// 配置默认文件(例如:Index.html)
app.UseDefaultFiles();
app.UseStaticFiles();
// 启用路由(如果有其他动态路由)
app.UseRouting();
}
}
步骤2:将 Index.html 设为默认文件
通过 app.UseDefaultFiles(),可以将 Index.html、default.html 等文件作为默认访问页面。
UseDefaultFiles 中间件会在访问根 URL 时自动查找默认文件。如果你的文件夹中有 Index.html 文件,当用户访问 http://localhost:5000 时,会自动加载 Index.html 文件。
步骤3:调整 DefaultFilesOptions(可选)
你还可以通过自定义 DefaultFilesOptions 来设置特定的默认文件。
示例:
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 自定义默认文件
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("Index.html"); // 设置为默认文件
app.UseDefaultFiles(options);
app.UseStaticFiles();
app.UseRouting();
}
}
在这个配置下,ASP.NET Core 将会将 Index.html 文件设置为默认页面。当你访问根路径 http://localhost:5000/ 时,Index.html 将自动加载。
步骤4:将 Index.html 放置在 wwwroot 目录下
确保你的 Index.html 文件放置在项目的 wwwroot 目录下。wwwroot 是 ASP.NET Core 项目中用于存放静态文件的文件夹。
目录结构示例:
/wwwroot
/css
/js
Index.html
完整的 Startup.cs 示例:
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 配置默认文件并启用静态文件服务
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("Index.html"); // 将 Index.html 设置为默认文件
app.UseDefaultFiles(options);
app.UseStaticFiles();
// 启用路由
app.UseRouting();
}
}
13、重定向URL
如果你需要对某些 URL 进行重定向(比如把访问 http://localhost:5000 重定向到 http://localhost:5000/home/index),可以在控制器或中间件中添加逻辑进行处理。
使用控制器重定向:
[ApiController]
[Route("")]
public class RedirectController : ControllerBase
{
[HttpGet("")]
public IActionResult RedirectToHome()
{
return RedirectToAction("Index", "Home");
}
}
这个控制器将会把根路径 / 重定向到 HomeController.Index()。
使用中间件重定向:
你也可以在 Startup.cs 文件中使用中间件来处理重定向:
app.Use(async (context, next) =>
{
if (context.Request.Path == "/")
{
context.Response.Redirect("/home/index");
}
else
{
await next();
}
});