Методы GET и POST с одинаковыми именами действий в одном контроллере - PullRequest
74 голосов
/ 04 марта 2012

Почему это неверно?

{
    public class HomeController : Controller
    {

        [HttpGet]
        public ActionResult Index()
        {
            Some Code--Some Code---Some Code
            return View();
        }

        [HttpPost]
        public ActionResult Index()
        {
            Some Code--Some Code---Some Code
            return View();
        }

    }

Как я могу иметь контроллер, который отвечает на один вопрос, когда он «получен», и один, когда «опубликован»?

Ответы [ 8 ]

159 голосов
/ 04 марта 2012

Поскольку у вас не может быть двух методов с одинаковыми именем и подписью, вы должны использовать атрибут ActionName:

    [HttpGet]
    public ActionResult Index()
    {
        Some Code--Some Code---Some Code
        return View();
    }

    [HttpPost]
    [ActionName("Index")]
    public ActionResult IndexPost()
    {
        Some Code--Some Code---Some Code
        return View();
    }

Также см. "Как метод становитсяАкция "

36 голосов
/ 04 марта 2012

Хотя ASP.NET MVC позволит вам выполнять два действия с одним и тем же именем, .NET не позволит вам иметь два метода с одной и той же сигнатурой - то есть одним и тем же именем и параметрами.

Вам нужно будет по-разному называть методы, используя атрибут ActionName, чтобы сообщить ASP.NET MVC, что на самом деле это одно и то же действие.

Тем не менее, если вы говорите о GET и POST, эта проблема, скорее всего, исчезнет, ​​поскольку действие POST будет принимать больше параметров, чем GET, и, следовательно, будет различимым.

Итак, вам нужно:

[HttpGet]
public ActionResult ActionName() {...}

[HttpPost, ActionName("ActionName")]
public ActionResult ActionNamePost() {...}

Или,

[HttpGet]
public ActionResult ActionName() {...}

[HttpPost]
public ActionResult ActionName(string aParameter) {...}
16 голосов
/ 10 августа 2012

Мне нравится принимать форму сообщения для моих действий POST, даже если мне это не нужно. Для меня это кажется правильным, потому что вы якобы публикуете что-то .

public class HomeController : Controller
{
    public ActionResult Index()
    {
        //Code...
        return View();
    }

    [HttpPost]
    public ActionResult Index(FormCollection form)
    {
        //Code...
        return View();
    }
}
5 голосов
/ 04 марта 2012

Чтобы ответить на ваш конкретный вопрос, вы не можете иметь два метода с одинаковым именем и одинаковыми аргументами в одном классе; использование атрибутов HttpGet и HttpPost не различает методы.

Чтобы решить эту проблему, я обычно включаю модель представления для формы, которую вы публикуете:

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        Some Code--Some Code---Some Code
        return View();
    }

    [HttpPost]
    public ActionResult Index(formViewModel model)
    {
        do work on model --
        return View();
    }

}
2 голосов
/ 04 марта 2012

Вы не можете иметь несколько действий с одним и тем же именем.Вы можете добавить параметр в один метод, и это будет допустимо.Например:

    public ActionResult Index(int i)
    {
        Some Code--Some Code---Some Code
        return View();
    }

Есть несколько способов сделать действия, которые отличаются только глаголом запроса.Мой любимый и, я думаю, самый простой для реализации - использовать пакет AttributeRouting .После установки просто добавьте атрибут к своему методу следующим образом:

  [GET("Resources")]
  public ActionResult Index()
  {
      return View();
  }

  [POST("Resources")]
  public ActionResult Create()
  {
      return RedirectToAction("Index");
  }

В приведенном выше примере методы имеют разные имена, но в обоих случаях имя действия называется «Ресурсы».Единственным отличием является глагол запроса.

Пакет можно установить с помощью NuGet следующим образом:

PM> Install-Package AttributeRouting

Если вы не хотите зависимостив пакетах AttributeRouting это можно сделать, написав атрибут селектора настраиваемого действия.

2 голосов
/ 04 марта 2012

Нельзя многократное действие с тем же именем и тем же параметром

    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Index(int id)
    {
        return View();
    }

althought int id не используется

1 голос
/ 17 декабря 2015

Вы получили хороший ответ на этот вопрос, но я хочу добавить свои два цента.Вы можете использовать один метод и обрабатывать запросы в соответствии с типом запроса:

public ActionResult Index()
{
    if("GET"==this.HttpContext.Request.RequestType)
    {
        Some Code--Some Code---Some Code for GET
    }
    else if("POST"==this.HttpContext.Request.RequestType)
    {
        Some Code--Some Code---Some Code for POST
    }
    else
    {
        //exception
    }

    return View();
}
0 голосов
/ 18 июня 2018

Сегодня я проверил некоторые ресурсы по тому же вопросу, и получил очень интересный пример.

Можно вызывать один и тот же метод по протоколам GET и POST, но вам необходимо перегрузить такие параметры:

@using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { @id = "form-consulta" }))
{
//code
}

Акция:

[ActionName("Index")]
public async Task<ActionResult> IndexAsync(MyModel model)
{
//code
}

По умолчанию метод без явного протокола - GET, но в этом случае есть объявленный параметр, который позволяет методу работать как POST.

При выполнении GET параметр не имеет значения, но при выполнении POST параметр требуется по вашему запросу.

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