Методы GET и POST с одинаковыми именами действий в одном контроллере

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

{
    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 ответов

Решение

Поскольку у вас не может быть двух методов с одинаковым именем и подписью, вы должны использовать 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();
    }

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

В то время как 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) {...}

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

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

    [HttpPost]
    public ActionResult Index(FormCollection form)
    {
        //Code...
        return View();
    }
}

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

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

Чтобы ответить на ваш конкретный вопрос, вы не можете иметь два метода с одинаковым именем и одинаковыми аргументами в одном классе; использование атрибутов 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();
    }

}

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

    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, вы можете сделать это, написав атрибут селектора настраиваемых действий.

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

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

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

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

Можно вызвать один и тот же метод по протоколу 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, параметр требуется по вашему запросу.

Другие вопросы по тегам