You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 MVC中asp-route-id传值为0引发空引用问题求助

问题描述

我正在开发ASP.NET Core 8 MVC项目,项目包含产品和客户两张数据表。当点击查看或编辑实体时,页面应加载对应的产品或客户信息,但出现了空引用异常。

经调试发现,调用详情视图时传递的ID值为0。明明系统能够正常获取并展示产品和客户列表,且我已经通过asp-route-id传递ID,请问这一问题的原因是什么?

相关代码

Dashboard.cshtml

<div class="row">
    <h2>Products</h2>
    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">Product Name</th>
                <th scope="col">Part Number</th>
                <th scope="col">UPC</th>
                <th scope="col">Price</th>
                <th scope="col">Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach(var product in @ViewBag.Products)
            {
                <tr>
                    <td>@product.Id</td>
                    <td>@product.ProductName</td>
                    <td>@product.PartNumber</td>
                    <td>@product.UPC</td>
                    <td>$@product.Price</td>
                    <td>
                        <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="ViewProductDetails" asp-route-id="@product.Id">View</a>
                        <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="UpdateProduct" asp-route-id="@product.Id">Update</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>
<div class="row">
    <h2>Clients</h2>
    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">Address</th>
                <th scope="col">Phone Number</th>
                <th scope="col">Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach(var client in @ViewBag.Clients)
            {
                <tr>
                    <td>@client.Id</td>
                    <td>@client.Address</td>
                    <td>@client.PhoneNumber</td>
                    <td>
                        <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="ViewClientDetails" asp-route-id="@client.Id">View</a>
                        <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="UpdateClient" asp-route-id="@client.Id">Update</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>

AdminController

public async Task<IActionResult> Dashboard()
{
    List<Client> clients = await _dbContext.Clients.OrderBy(client => client.Id).ToListAsync();
    List<Product> products = await _dbContext.Products.OrderBy(products => products.Id).ToListAsync();
    // Gets both Lists just fine and displays them
    ViewBag.Clients = clients;
    ViewBag.Products = products;
    return View();
}

// Other code
// These methods are doing the same behavior. int of either productId or clientId are 0
// It shouldn't be 0

public async Task<IActionResult> UpdateProduct(int productId)
{
    Product prod = await _dbContext.Products.FirstOrDefaultAsync(product => product.Id == productId);
    return View(prod);
}

public async Task<IActionResult> ViewProductDetails(int productId)
{
    Product prod = await _dbContext.Products.FirstOrDefaultAsync(product => product.Id == productId);
    return View(prod);
}

public async Task<IActionResult> UpdateClient(int clientId)
{
    Client client = await _dbContext.Clients.FirstOrDefaultAsync(client => client.Id == clientId);
    return View(client);
}

public async Task<IActionResult> ViewClientDetails(int clientId)
{
    Client client = await _dbContext.Clients.FindAsync(clientId);
    return View(client);
}
原因及解决方法

核心问题是路由参数名称与控制器方法参数名称不匹配:

  • 视图中通过asp-route-id传递的参数名为id,但控制器方法接收的参数名是productId或clientId。ASP.NET Core的模型绑定无法自动匹配不同名称的参数,因此会给int类型的参数赋予默认值0,最终导致查询不到数据引发空引用异常。

有两种修复方式可选:

方式一:修改控制器参数名,匹配路由参数

将控制器方法的参数名改为id,和视图中传递的参数名保持一致:

public async Task<IActionResult> UpdateProduct(int id)
{
    Product prod = await _dbContext.Products.FirstOrDefaultAsync(product => product.Id == id);
    return View(prod);
}

public async Task<IActionResult> ViewProductDetails(int id)
{
    Product prod = await _dbContext.Products.FirstOrDefaultAsync(product => product.Id == id);
    return View(prod);
}

public async Task<IActionResult> UpdateClient(int id)
{
    Client client = await _dbContext.Clients.FirstOrDefaultAsync(client => client.Id == id);
    return View(client);
}

public async Task<IActionResult> ViewClientDetails(int id)
{
    Client client = await _dbContext.Clients.FindAsync(id);
    return View(client);
}

方式二:修改视图路由参数名,匹配控制器参数

调整视图中asp-route-*的后缀,使其和控制器方法的参数名一致:

<!-- 产品操作链接修改后 -->
<td>
    <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="ViewProductDetails" asp-route-productId="@product.Id">View</a>
    <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="UpdateProduct" asp-route-productId="@product.Id">Update</a>
</td>

<!-- 客户操作链接修改后 -->
<td>
    <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="ViewClientDetails" asp-route-clientId="@client.Id">View</a>
    <a class="btn btn-primary" asp-area="" asp-controller="Admin" asp-action="UpdateClient" asp-route-clientId="@client.Id">Update</a>
</td>

额外建议

为控制器参数添加[Required]特性,这样当参数未正确传递时,会直接返回400错误,避免默认值导致的隐性问题:

public async Task<IActionResult> UpdateProduct([Required] int productId)
{
    // ...
}

内容的提问来源于stack exchange,提问作者DonDavid12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:24:53