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


131

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

我有一个既可以接受GET请求也可以接受POST请求的操作,并且我希望能够RedirectToAction使用POST并将其发送一些值。

像这样:

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

我希望someValueanotherValue值使用HTTP POST而不是GET发送。有谁知道如何做到这一点?


杰森发布的答案将在大多数情况下都可以使用,我看到的唯一问题是它容易发生事故。即,直接调用动作方法将绕过应用于该动作的所有过滤器。因此,如果对操作方法应用了任何身份验证或计数器类型的筛选器,则该数据可能会丢失。直接调用操作方法可以使用,但应谨慎使用。
amarnath chatterjee

Answers:


103

HTTP不支持使用POST重定向到页面。当您重定向到某处时,HTTP“ Location”标头告诉浏览器要去哪里,浏览器对该页面进行GET请求。您可能只需要编写页面代码即可接受GET请求和POST请求。


4
很好奇为什么我的答案不被接受,我认为我的言论是正确的。:)再说一次,我可能对此有些偏见……
Jason Bunting,2010年

14
虽然这个答案基本上是正确的,但并不完整。请参阅下面的Jason Bunting答案,以获得更好的解决方法。
Adrian Grigore

160

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

[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,这就是您在答案中发布的链接所建议的内容。

我很想知道这是什么“错”,如果有的话。显然,如果您确实希望将重定向发送到浏览器,则将无法正常工作,但是您应该问为什么无论如何都要进行转换,因为这对我来说似乎很奇怪。

希望有帮助。


7
谁知道你为什么被拒绝。这是一个非常有用的方法。
彼得·J

2
这也是我始终解决此问题的方式。拒绝投票是没有意义的。
Adrian Grigore

39
我投了赞成票,尽管我不同意在您不认识白痴时称呼他们为白痴。
Jim Schubert

3
我不是一个拒绝投票的人,但是这样做的一个警告是,如果您要使用不同的名称调用视图,或者如果参数很重要,则它们将丢失。原因是URL将在服务器端重定向之前反映操作和参数。这可能会导致用户感到困惑,尤其是当用户刷新页面然后发现自己位于上一页时(因为刷新使用的是旧的URL)。这项技术本质上与asp.net的Server.Transfer非常相似,应谨慎行事。
AaronLS 2012年

15
我本身并没有投票,但是我可以看到理由。此方法违反了MVC模式设置的编码约定。它只是调用同样的动作时的作品。如果该动作是另一个动作,即使在同一控制器上,也将拧紧路由值,并且将返回错误的视图。简而言之:不要这样做。
erlando 2012年

21

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

行动

TempData["datacontainer"] = modelData;

视图

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

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

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


11

试试这个

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>");

2
讨厌但喜欢它:)
divinci

这样的破解,但这是我可以做自己想要的事而又不违反DRY或重新布线整个设置的唯一方法!谢谢!
jamheadart

6

我想扩大Jason Bunting的答案

像这样

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

Eli将会在这里对如何使其成为通用变量提出一些想法

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.