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

.NET Framework 4.6.1中Post方法失败后重定向至另一个Post方法的问题

解决Post方法重定向到区域Post方法的问题

在.NET Framework 4.6.1里,RedirectToAction默认返回302重定向,浏览器会自动把原Post请求改成Get请求,而你的目标方法是Post,所以会出现NotFound错误。下面是几个可行的解决办法:

方法1:返回307临时重定向(保留请求方法)

HTTP 307状态码会告诉浏览器保留原请求方法访问新地址,这样就能带着Post请求跳转到目标方法。你可以自定义重定向结果,或者手动设置响应头:

自定义重定向结果类

public class RedirectToActionPreserveMethodResult : ActionResult
{
    public string ActionName { get; set; }
    public string ControllerName { get; set; }
    public RouteValueDictionary RouteValues { get; set; }

    public RedirectToActionPreserveMethodResult(string actionName, string controllerName, RouteValueDictionary routeValues)
    {
        ActionName = actionName;
        ControllerName = controllerName;
        RouteValues = routeValues;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var urlHelper = new UrlHelper(context.RequestContext);
        var url = urlHelper.Action(ActionName, ControllerName, RouteValues);
        
        context.HttpContext.Response.StatusCode = 307;
        context.HttpContext.Response.RedirectLocation = url;
    }
}

在你的Post方法A()中使用

[HttpPost]
[Route("{customerName}/Home/A")]
public ActionResult A(string customerName, string id)
{
    try
    {
        // 你的业务逻辑,执行失败则进入catch
        return View();
    }
    catch (Exception)
    {
        // 重定向到FirstCustomer区域的Home/A Post方法
        return new RedirectToActionPreserveMethodResult("A", "Home", new { area = "FirstCustomer", id = id });
    }
}

注意:307重定向会让浏览器重复提交原请求的表单数据,要避免用户重复提交产生副作用(比如重复下单),同时部分旧浏览器对307支持有限,需要测试兼容性。

方法2:前端自动提交表单(更稳妥)

如果担心307的兼容性问题,可以返回一个临时视图,通过隐藏表单自动提交到目标地址:

在你的Post方法A()中返回临时视图

[HttpPost]
[Route("{customerName}/Home/A")]
public ActionResult A(string customerName, string id)
{
    try
    {
        // 业务逻辑
        return View();
    }
    catch (Exception)
    {
        // 传递需要的参数
        TempData["Id"] = id;
        return View("RedirectToCustomerPost");
    }
}

创建RedirectToCustomerPost视图

@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Redirecting...</title>
    <script>
        window.onload = function() {
            document.getElementById("redirectForm").submit();
        };
    </script>
</head>
<body>
    <form id="redirectForm" action="@Url.Action("A", "Home", new { area = "FirstCustomer" })" method="post">
        @Html.Hidden("id", TempData["Id"])
        <!-- 其他需要传递的隐藏字段 -->
        <p>Redirecting, please wait...</p>
    </form>
</body>
</html>

这个方法兼容性拉满,所有浏览器都支持,还能清晰控制传递的参数,可按需添加防重复提交逻辑。

方法3:直接调用目标方法的逻辑(服务器内部处理)

如果不需要浏览器跳转,只是想复用目标方法的业务逻辑,可以直接实例化区域的HomeController并调用其方法:

[HttpPost]
[Route("{customerName}/Home/A")]
public ActionResult A(string customerName, string id)
{
    try
    {
        // 业务逻辑
        return View();
    }
    catch (Exception)
    {
        // 实例化FirstCustomer区域的HomeController
        var targetController = new FirstCustomer.Controllers.HomeController();
        // 复制当前请求上下文到目标控制器
        targetController.ControllerContext = new ControllerContext(this.ControllerContext.RequestContext, targetController);
        // 调用目标方法并传递参数
        return targetController.A(id);
    }
}

注意:这种方式是服务器内部转发,不会改变浏览器地址栏,要确保目标控制器的依赖注入(如果有)能正常工作,避免空引用问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:57:34