使用相同的方法签名进行POST和GET请求

60
在我的控制器中,我有两个名为“Friends”的操作。执行哪个取决于它是“get”还是“post”。因此,我的代码片段看起来像这样:
// Get:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

// Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

然而,这段代码无法编译,因为我有两个具有相同签名(Friends)的方法。我该如何创建它?我需要创建一个动作,但在其中区分“get”和“post”吗?如果是这样,我该如何做到?

7个回答

130

将第二个方法重命名为其他名称,例如"Friends_Post",然后您可以在第二个方法上添加[ActionName("Friends")]属性。这样,使用POST请求类型访问“Friend”动作的请求将由该动作处理。

// Get:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

// Post:
[ActionName("Friends")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends_Post()
{
    // do some stuff
    return View();
}

9
自 MVC 2.0 以来,[AcceptVerbs(HttpVerbs.Get)] 可以缩写为 [HttpGet],其他 REST 方法也是如此。 - Julian Krispel-Samsel

25

如果你确实想要一个例程来处理两个动词,请尝试这样做:

[AcceptVerbs("Get", "Post")]
public ActionResult ActionName(string param1, ...)
{
//Fun stuff goes here.
}

有一个潜在的警告:我在使用MVC发布版本2。不确定在MVC 1中是否支持此功能。AcceptVerbs的Intellisense文档应该可以让您知道。


3
由于其构造函数被定义为AcceptVerbsAttribute(params string[] verbs),因此[AcceptVerbs("Get","Post")]应该有效,看起来更整洁。 - jamiebarrow
谢谢!我更喜欢那个。 - RameyRoad
更重要的是,[HttpGet][HttpPost] 失败了,因为它们各自的设计只允许一个类型。 - John Lord

10

尝试使用:

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

3

我不完全确定这是否是正确的方法,但我会使用一个无意义的参数来区分签名。例如:

// Get:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Friends(bool isGet)
{
    // do some stuff
    return View();
}

// Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

我知道这很丑陋而且是一种刻意的hack,但它可以运行。

3

因为cagdas的回答解决了我的问题,所以我将其标记为答案。但是,由于我不喜欢在项目中使用ActionName属性,所以我使用了另一种解决方案。我只是将FormCollection添加到“post”操作中(这最终会更改方法签名)。

// Get:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}

// Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends(FormCollection form)
{
    // do some stuff
    return View();
}

最好使用更加类型化的方法来接收发布的内容-请参阅答案。 - Matt Kocaj

1
在Post方法中添加想要接收的参数。可能像这样:
// Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends(string friendName, string otherField)
{
    // do some stuff
    return View();
}

或者如果你有一个像这样的复杂类型:

// Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends(Friend friend)
{
    // do some stuff
    return View();
}

编辑:最好使用更加类型化的方法来接收已发布的项目,就像上面那样。


0

你的操作方法不能做同样的事情,否则就没有必要编写两个操作方法了。所以,如果语义不同,为什么不为操作方法使用不同的名称呢?

例如,如果您有一个“删除”操作方法,并且 GET 方法只是请求确认,则可以将 GET 方法称为“ConfirmDelete”,POST 方法称为“Delete”。

不确定是否符合您的情况,但当我遇到相同的问题时,这种方法总能派上用场。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接