ASP.NET Core控制器无法获取路由Id值?问题排查与解决方法
问题出在路由参数名称与控制器方法参数名称不匹配:
你的跳转URL是https://localhost:xxxx/InventoryRequestDetails/Index/1,其中最后一段的1对应默认路由模板中的id参数,但控制器方法的参数名是InventoryRequestId,ASP.NET Core模型绑定默认按名称匹配,所以无法将路由中的id值绑定到InventoryRequestId参数上,导致参数值为int类型的默认值0。
下面是三种可行的解决方法:
方法1:修改视图中的路由参数名称,匹配控制器参数
将视图里的asp-route-id改为asp-route-inventoryRequestId,这样生成的请求会把参数名和值正确传递给控制器:
<a asp-controller="InventoryRequestDetails" asp-action="Index" asp-route-inventoryRequestId="@item.InventoryRequestId">Details</a>
修改后生成的URL会变为https://localhost:xxxx/InventoryRequestDetails/Index?InventoryRequestId=1(或符合自定义路由模板的格式),控制器的InventoryRequestId参数就能正确获取到值。
方法2:修改控制器参数名称,匹配路由中的id
把控制器方法的参数名从InventoryRequestId改为id,让它和默认路由的参数名匹配:
public async Task<IActionResult> Index(int id) { _logger.LogInformation($"查找ID为{id}的InventoryRequest"); var inventoryRequest = await _context.InventoryRequests.FindAsync(id); _logger.LogInformation($"找到的InventoryRequest: {inventoryRequest}"); if (inventoryRequest == null) { return NotFound(); } ViewBag.RequestNumber = inventoryRequest.RequestNumber; var applicationDbContext = _context.InventoryRequestDetails .Include(i => i.Inventaris) .Include(i => i.InventoryRequest) .Where(w => w.InventoryRequestId == id); return View(await applicationDbContext.ToListAsync()); }
这种方法不需要修改视图,URL保持原格式即可正常绑定。
方法3:用[FromRoute]特性显式指定绑定来源
如果不想修改参数名或视图代码,可以给控制器参数添加[FromRoute]特性,明确指定从路由的id参数获取值:
public async Task<IActionResult> Index([FromRoute(Name = "id")] int InventoryRequestId) { _logger.LogInformation($"查找ID为{InventoryRequestId}的InventoryRequest"); var inventoryRequest = await _context.InventoryRequests.FindAsync(InventoryRequestId); _logger.LogInformation($"找到的InventoryRequest: {inventoryRequest}"); if (inventoryRequest == null) { return NotFound(); } ViewBag.RequestNumber = inventoryRequest.RequestNumber; var applicationDbContext = _context.InventoryRequestDetails .Include(i => i.Inventaris) .Include(i => i.InventoryRequest) .Where(w => w.InventoryRequestId == InventoryRequestId); return View(await applicationDbContext.ToListAsync()); }
这种方法保持原代码结构不变,仅通过特性告诉框架如何绑定参数。
验证方式
可以查看日志输出的InventoryRequestId(或id)值是否为URL中的1,或者在控制器方法内添加断点,调试确认参数是否正确获取到值。
内容的提问来源于stack exchange,提问作者Haminteu

