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

ASP.NET MVC中带HttpPost的同名控制器方法未被调用问题

ASP.NET MVC 路由匹配问题:无法触发带[HttpPost]的Details方法

我在开发一个集成Rest API的ASP.NET MVC项目时遇到了问题:控制器里有两个同名的Details方法,一个带[HttpPost]特性,另一个没有HTTP动词标注。但运行时总是调用无标注的那个,我想要触发带HttpPost的方法。

控制器代码示例

// GET: NormUserController/Details/5
public IActionResult Details(BankAccount account)
{
    if (account != null)
    {
        Console.WriteLine("con" + account.IdUser);
        return View(account);
    }

    return RedirectToAction("Index");
}

[HttpPost]
public async Task<IActionResult> Details(int IdAccount)
{
    Console.WriteLine("starting post");
    var account = await servicio_APIBAccount.Obtener(IdAccount);
    Console.WriteLine("Account: " +  account.IdAccount);

    if (account != null)
    {
        Console.WriteLine("Id Account " + account.IdAccount);
        return View("Edit", account);
    }

    Console.WriteLine("Failed");

    return RedirectToAction("Index");
}

对应的Razor视图代码

@model BankAccount

@{
    ViewData["Title"] = "Estado de cuenta";
}

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<link href="~/css/site.css" rel="stylesheet">

<div class="card" style="width: 18rem;">
    <h2>@ViewData["Title"]</h2>
    <div class="card-body">
        <h4>Cuenta de ahorro</h4>
        <table class="table table-borderless">
            <tr>
                <td>Número de cuenta:</td>
                <td></td>
                <td></td>
                <td>@Model.AccountNumber</td>
            </tr>
            <tr>
                <td>Saldo disponible:</td>
                <td></td>
                <td></td>
                <td>$@Model.AccountAmount</td>
            </tr>
            </table>
    </div>
</div>

<div>
    <a asp-action="Details" asp-controller="NormUser" class="button button-accion">Transferencias</a>
    <a asp-action="Index" asp-controller="Home" class="button cerrar-sesion">Cerrar Sesión</a>
</div>

问题原因及解决办法

核心原因

视图里的"Transferencias"按钮用的是<a>标签,这类标签默认发送GET请求,而ASP.NET MVC中无HTTP动词标注的方法默认接受GET请求,所以会匹配到不带[HttpPost]的Details方法;带[HttpPost]的方法只接受POST请求,自然不会被触发。

解决步骤

方法一:改用表单提交(推荐)

把<a>标签替换成表单,通过POST请求触发目标方法,同时传递必要参数:

<div>
    <form asp-action="Details" asp-controller="NormUser" method="post">
        <input type="hidden" name="IdAccount" value="@Model.IdAccount" />
        <button type="submit" class="button button-accion">Transferencias</button>
    </form>
    <a asp-action="Index" asp-controller="Home" class="button cerrar-sesion">Cerrar Sesión</a>
</div>

点击按钮时会发送POST请求,匹配到带[HttpPost]的Details方法,隐藏字段会把当前账户的IdAccount传递过去。

方法二:给GET方法显式添加[HttpGet]特性

虽然不能直接解决POST触发问题,但能让路由规则更清晰,避免歧义:

[HttpGet]
public IActionResult Details(BankAccount account)
{
    // 原有代码逻辑
}

方法三:用AJAX发送POST请求(无刷新场景)

如果需要页面无刷新提交,可以用AJAX实现:

@Html.AntiForgeryToken()
<div>
    <button class="button button-accion" data-id="@Model.IdAccount">Transferencias</button>
    <a asp-action="Index" asp-controller="Home" class="button cerrar-sesion">Cerrar Sesión</a>
</div>

<script>
document.querySelector('.button-accion').addEventListener('click', function(e) {
    e.preventDefault();
    const id = this.getAttribute('data-id');
    fetch('/NormUser/Details', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
        },
        body: `IdAccount=${id}`
    }).then(response => {
        if (response.ok) {
            window.location.href = response.url;
        }
    });
});
</script>

注意要添加防伪令牌(@Html.AntiForgeryToken()),避免跨站请求伪造。

额外提示

确保POST方法需要的IdAccount参数能正确传递,比如从当前视图的Model中获取,否则会导致参数为空,影响后续的API调用逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:42:53