разместить и получить с тем же методом подписи - PullRequest
51 голосов
/ 07 апреля 2009

В моем контроллере у меня есть два действия под названием «Друзья». То, что выполняется, зависит от того, будет ли это «получить» или «опубликовать».

Итак, мои фрагменты кода выглядят примерно так:

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

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

Однако, это не компилируется, так как у меня есть два метода с одинаковой подписью (Друзья). Как мне создать это? Нужно ли создавать только одно действие, но различать «получить» и «отправлять» внутри него? Если да, то как мне это сделать?

Ответы [ 7 ]

115 голосов
/ 07 апреля 2009

Переименуйте второй метод во что-то еще, например "Friends_Post", и затем вы можете добавить атрибут [ActionName("Friends")] ко второму. Таким образом, запросы к действию Friend с POST в качестве типа запроса будут обрабатываться этим действием.

// 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();
}
20 голосов
/ 12 июля 2010

Если вы действительно хотите, чтобы только одна процедура обрабатывала оба глагола, попробуйте следующее:

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

Одно потенциальное предостережение: я использую MVC версии 2. Не уверен, что это поддерживается в MVC 1. Документация Intellisense для AcceptVerbs должна сообщить вам.

6 голосов
/ 27 июля 2012

Попробуйте использовать:

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult Friends()
{
    // do some stuff
    return View();
}
2 голосов
/ 07 апреля 2009

Отметить ответ 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();
}
2 голосов
/ 07 апреля 2009

не совсем уверен, что это правильный путь, но я бы использовал бессмысленный параметр, чтобы отличить сигы. как:

// 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();
}

Я знаю, что это уродливо и хакерски, но это работает.

1 голос
/ 07 апреля 2009

добавьте к методу 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 голосов
/ 20 декабря 2010

Ваши методы действия не могут делать одно и то же, иначе не было бы необходимости писать два метода действия. Так что, если семантика различна, почему бы не использовать разные имена для методов действия?

Например, если у вас был метод действия «удалить» и GET просто запрашивает подтверждение, вы можете вызвать метод GET «ConfirmDelete», а метод POST просто «Удалить».

Не уверен, что это соответствует вашему сценарию, но это всегда было для меня, когда у меня была такая же проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...