如何使用 POST 动词重定向到页面?

Posted

技术标签:

【中文标题】如何使用 POST 动词重定向到页面?【英文标题】:How do you redirect to a page using the POST verb? 【发布时间】:2010-09-12 20:40:16 【问题描述】:

当您在控制器中调用 RedirectToAction 时,它会使用 HTTP GET 自动重定向。如何明确告诉它使用 HTTP POST?

我有一个同时接受 GET 和 POST 请求的操作,我希望能够使用 POST RedirectToAction 并向其发送一些值。

像这样:

this.RedirectToAction(
    "actionname",
    new RouteValueDictionary(new  someValue = 2, anotherValue = "text" )
);

我希望使用 HTTP POST 而不是 GET 发送 someValueanotherValue 值。有人知道怎么做吗?

【问题讨论】:

jason 发布的答案适用于大多数情况,我看到的唯一问题是它容易发生事故。即直接调用操作方法绕过应用于操作的所有过滤器。因此,如果对操作方法应用了任何身份验证或计数器类型的过滤器,则该数据可能会丢失。直接调用 action 方法会起作用,但应谨慎应用。 【参考方案1】:

对于您的特定示例,我会这样做,因为您显然并不关心实际上让浏览器获得重定向(通过接受您已经接受的答案):

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index() 
   // obviously these values might come from somewhere non-trivial
   return Index(2, "text");


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int someValue, string anotherValue) 
   // would probably do something non-trivial here with the param values
   return View();

这很容易工作,并且没有真正发生有趣的事情 - 这使您可以保持第二个确实只接受 HTTP POST 请求的事实(除了在这种情况下,它无论如何都在您的控制之下)并且您不接受也不必使用 TempData,这是您在答案中发布的链接所暗示的。

如果有什么问题,我很想知道这有什么“错误”。显然,如果您真的想向浏览器发送重定向,这是行不通的,但是您应该问为什么无论如何都要尝试转换它,因为这对我来说似乎很奇怪。

希望对您有所帮助。

【讨论】:

谁知道你为什么被否决。这是一个非常有用的方法。 这也是我一直解决这个问题的方法。对此投反对票是没有意义的。 我投了赞成票,虽然我不同意在你不认识他们的情况下称他们为白痴。 我不是反对者,但需要注意的一点是,如果您要使用不同的名称调用视图,或者如果参数很重要,它们就会丢失。原因是 URL 将在服务器端重定向之前反映操作+参数。这可能会导致用户混淆,尤其是当他们刷新页面然后发现自己在前一页面时(因为刷新使用了旧 URL)。这种技术本质上与 asp.net 的 Server.Transfer 非常相似,同样需要注意。 我本身并没有投反对票,但我可以看到理由。这种方法违反了 MVC 模式建立的编码约定。它在调用相同操作时起作用。如果 action 是另一个,即使在同一个控制器上,路由值也会出错,并且会返回错误的视图。简而言之:不要这样做。【参考方案2】:

HTTP 不支持使用 POST 重定向到页面。当你重定向到某个地方时,HTTP“位置”标头告诉浏览器去哪里,浏览器对该页面发出 GET 请求。您可能只需要为您的页面编写代码以接受 GET 请求和 POST 请求。

【讨论】:

很好奇为什么我的回答不被接受,我认为我的言辞是合理的。 :) 再说一次,我可能对此有点偏见...... 虽然这个答案基本正确,但并不完整。请参阅下面的 Jason Bunting 答案以获得更好的解决方法。【参考方案3】:

如果您想在重定向期间在两个操作之间传递数据而不在查询字符串中包含任何数据,请将模型放在 TempData 对象中。

动作

TempData["datacontainer"] = modelData;

查看

var modelData= TempData["datacontainer"] as ModelDataType; 

TempData 是一个非常短暂的实例,您应该只在当前和后续请求期间使用它!由于 TempData 以这种方式工作,您需要确定下一个请求将是什么,并且重定向到另一个视图是您唯一可以保证这一点的时间。

因此,使用 TempData 可靠工作的唯一情况是在重定向时。

【讨论】:

【参考方案4】:

试试这个

return Content("<form action='actionname' id='frmTest' method='post'><input type='hidden' name='someValue' value='" + someValue + "' /><input type='hidden' name='anotherValue' value='" + anotherValue + "' /></form><script>document.getElementById('frmTest').submit();</script>");

【讨论】:

讨厌但喜欢它:) 这样的黑客,但这是我可以做我想做的事而不违反 DRY 或重新布线我的整个设置的唯一方法!谢谢!【参考方案5】:

我想扩展 Jason Bunting 的答案

喜欢这个

ActionResult action = new SampelController().Index(2, "text");
return action;

Eli 会在这里讨论如何使其成为通用变量的想法

可以获得所有类型的控制器

【讨论】:

您不应使用new ...() 为控制器创建实例,因为您将丢失RequestContext - 如果您已经在同一个控制器中,则可能不需要创建新实例。否则,采取以下方式:SampelController sampleController = DependencyResolver.Current.GetService&lt;SampelController&gt;() then:sampleController.ControllerContext = new ControllerContext(Request.RequestContext, sampleController); then you can return sampleController.Index(2, "text"); just a hint :)【参考方案6】:

我刚刚遇到了同样的问题。

解决方案是像函数一样调用控制器动作:

return await ResendConfirmationEmail(new ResendConfirmationEmailViewModel()  Email = input.Email );

控制器动作:

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> ResendConfirmationEmail(ResendConfirmationEmailViewModel input)

    ...
 
    return View("ResendConfirmationEmailConfirmed");

【讨论】:

这很好,但只能在同一个控制器中实现。从另一个控制器,您需要一个实例来调用该方法,例如 new EmailController().ResendConfirmationEmail(...); ?

以上是关于如何使用 POST 动词重定向到页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何向可能重定向到登录页面的页面发出 POST 请求

使用后台代码中的 Post 方法重定向到另一个页面

如何使用 JQuery 重定向,加载另一个页面但在请求中发送了一些 POST 参数?

如何在 Django 2 中的 POST 方法后重定向到成功

当引导验证成功时,如何使用 $.post 提交表单而不进行页面重定向?

如何在获取 post 调用后管理重定向请求