web-dev-qa-db-fra.com

GET et POST méthodes avec le même nom d'action dans le même contrôleur

Pourquoi est-ce incorrect?

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

    }

Comment puis-je avoir un contrôleur qui réponde une chose quand est "getter" et une quand est "posté"?

72
Ricardo Polo

Puisque vous ne pouvez pas avoir deux méthodes avec le même nom et la même signature, vous devez utiliser l'attribut 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();
    }

Voir aussi "Comment une méthode devient une action"

151
BrokenGlass

Alors que ASP.NET MVC vous permettra d’avoir deux actions avec le même nom, .NET ne vous autorisera pas avec deux méthodes avec la même signature - c’est-à-dire le même nom et les mêmes paramètres.

Vous devrez nommer les méthodes différemment. Utilisez l'attribut ActionName pour indiquer à ASP.NET MVC qu'il s'agit en fait de la même action.

Cela dit, si vous parlez d'un GET et d'un POST, ce problème disparaîtra probablement, car l'action POST prendra plus de paramètres que le GET et pourra donc être distinguée.

Donc, vous devez soit:

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

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

Ou,

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

[HttpPost]
public ActionResult ActionName(string aParameter) {...}
35
user1082916

J'aime accepter un message de formulaire pour mes actions POST, même si je n'en ai pas besoin. Pour moi, je pense que c'est la bonne chose à faire puisque vous postulez soi-disantquelque chose.

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

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

Pour répondre à votre question spécifique, vous ne pouvez pas avoir deux méthodes avec le même nom et les mêmes arguments dans une même classe; L'utilisation des attributs HttpGet et HttpPost ne distingue pas les méthodes.

Pour résoudre ce problème, j'inclus généralement le modèle d'affichage du formulaire que vous publiez:

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

}
5
Jeff Siver

Ne peut pas multi-action même nom et même paramètre

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

althought int id n'est pas utilisé

2
Mason

Vous ne pouvez pas avoir plusieurs actions avec le même nom. Vous pouvez ajouter un paramètre à une méthode et cela serait valide. Par exemple:

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

Il existe plusieurs façons d’avoir des actions qui ne diffèrent que par le verbe à la demande. Mon préféré et, je pense, le plus facile à implémenter est d’utiliser le paquet AttributeRouting . Une fois installé, ajoutez simplement un attribut à votre méthode comme suit:

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

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

Dans l'exemple ci-dessus, les méthodes ont des noms différents mais le nom de l'action dans les deux cas est "Ressources". La seule différence est le verbe de la demande.

Le paquet peut être installé en utilisant NuGet comme ceci:

PM> Install-Package AttributeRouting 

Si vous ne voulez pas de dépendance vis-à-vis des packages AttributeRouting, vous pouvez le faire en écrivant un attribut de sélecteur d'action personnalisé.

2
Mark

Vous avez reçu la bonne réponse à cette question, mais je veux ajouter mes deux cents. Vous pouvez utiliser une méthode et traiter les demandes en fonction du type de demande:

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

Aujourd'hui, je vérifiais certaines ressources sur la même question et j'ai eu un exemple très intéressant.

Il est possible d'appeler la même méthode par GET et le protocole POST, mais vous devez surcharger les paramètres de la manière suivante:

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

L'action:

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

Par défaut, une méthode sans protocole explicite est GET, mais dans ce cas, il existe un paramètre déclaré qui permet à la méthode de fonctionner comme un POST.

Lorsque GET est exécuté, le paramètre n'a pas d'importance, mais lorsque POST est exécuté, le paramètre est obligatoire sur votre demande.

0
Moacir