Blazor Web应用按分类查询遇500错误及路由歧义问题
Blazor Web应用按分类查询数据的问题及解决
问题背景
Blazor Web应用(Auto模式)中,客户端从数据库获取全量数据的服务和控制器可正常工作,但按分类查询特定数据时先触发500内部服务器错误,调整后又出现端点匹配歧义错误:
An unhandled exception occurred while processing the request.
AmbiguousMatchException: The request matched multiple endpoints. Matches:Design_A_Bear.Controllers.ItemController.GetItemsByCategory (Design_A_Bear)
Design_A_Bear.Controllers.ItemController.GetItemById (Design_A_Bear)
核心原因是两个带参数的GET方法路由路径冲突:
- 按分类查询的请求路径为
/api/Item/{category} - 按ID查询的请求路径为
/api/Item/{id}
ASP.NET Core无法区分字符串类型的category和整数类型的id,导致服务器无法确定要调用的端点。
相关代码片段
IItemService.cs
Task<List<Item>> GetItemsByCategory(string category);
ItemService.cs
public async Task<List<Item>> GetItemsByCategory(string category) { List<Item> items = await _db.Items.Where(item => item.Category == category).ToListAsync(); return items; }
ClientItemService.cs(原代码)
public async Task<List<Item>> GetItemsByCategory(string category) { var result = await _httpClient.GetFromJsonAsync<List<Item>>($"/api/Item/{category}"); return result; } public async Task<Item> GetItemById(int id) { var result = await _httpClient.GetFromJsonAsync<Item>($"/api/Item/{id}"); return result; }
ItemController.cs(原代码)
[HttpGet("{category}")] public async Task<ActionResult> GetItemsByCategory(string category) { var items = await _itemServices.GetItemsByCategory(category); return Ok(items); } // 按ID查询的控制器方法 [HttpGet("{id}")] public async Task<ActionResult<Item>> GetItemById(int id) { var item = await _itemServices.GetItemById(id); return Ok(item); }
解决方案
通过修改控制器路由规则明确区分两个端点,同时同步调整客户端请求路径:
1. 修改控制器路由
给按分类查询的方法添加固定路由前缀,给按ID查询的方法添加参数类型约束:
// 按分类查询:路径改为/api/Item/category/{category} [HttpGet("category/{category}")] public async Task<ActionResult> GetItemsByCategory(string category) { var items = await _itemServices.GetItemsByCategory(category); return Ok(items); } // 按ID查询:添加int类型约束,确保仅整数参数匹配此端点 [HttpGet("{id:int}")] public async Task<ActionResult<Item>> GetItemById(int id) { var item = await _itemServices.GetItemById(id); return Ok(item); }
2. 调整客户端请求路径
同步修改ClientItemService中的请求路径,匹配控制器的新路由:
public async Task<List<Item>> GetItemsByCategory(string category) { var result = await _httpClient.GetFromJsonAsync<List<Item>>($"/api/Item/category/{category}"); return result; } // 按ID查询路径保持不变,因控制器添加了int类型约束,不会与分类查询冲突 public async Task<Item> GetItemById(int id) { var result = await _httpClient.GetFromJsonAsync<Item>($"/api/Item/{id}"); return result; }
额外说明
最初的500内部服务器错误大概率是端点匹配歧义导致服务器无法正确处理请求,解决歧义后该错误会随之消失。
内容的提问来源于stack exchange,提问作者Mat
相关产品推荐
相关产品推荐

