Методы 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();
        }

    }

Как я могу иметь контроллер, который отвечает на одну вещь, когда" getted "и один, когда"posted"?

8 69

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) {...}

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

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

    [HttpPost]
    public ActionResult Index(FormCollection form)
    {
        //Code...
        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();
    }

}

Не может мульти действие то же имя и тот же параметр

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

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

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

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

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

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

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

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

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

действие:

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

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

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