web-dev-qa-db-fra.com

MVC [HttpPost / HttpGet] pour action

J'utilise MVC C #.

Quelqu'un peut-il donner un exemple de la raison pour laquelle on utiliserait

[HttpPost/HttpGet] 

pour une action. Comment un actif peut-il avoir les deux - quelle est l'utilisation pratique?

51
Nate Pet

Supposons que vous avez une action Login qui fournit à l'utilisateur un écran de connexion, puis reçoit le nom d'utilisateur et le mot de passe après que l'utilisateur a soumis le formulaire:

public ActionResult Login() {
    return View();
}

public ActionResult Login(string userName, string password) {
    // do login stuff
    return View();
}

On ne donne pas à MVC des instructions claires sur les actions à prendre, même si on peut les déterminer en les regardant. Si vous ajoutez [HttpGet] à la première action et [HttpPost] à l'action de la section, MVC sait clairement quelle action est laquelle.

Pourquoi? Voir Méthodes de demande . Long et court: lorsqu'un utilisateur consulte une page, il s'agit d'une requête GET et lorsqu'un utilisateur soumet un formulaire, il s'agit généralement d'une requête POST. HttpGet et HttpPost limitent simplement l'action au type de requête applicable). .

[HttpGet]
public ActionResult Login() {
    return View();
}

[HttpPost]
public ActionResult Login(string userName, string password) {
    // do login stuff
    return View();
}

Vous pouvez également combiner les attributs de méthode de requête si votre action répond aux requêtes de plusieurs verbes:

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)].

83
Jesse Hallam

Vous n'avez pas besoin de spécifier les deux en même temps, sauf si vous limitez spécifiquement les autres verbes (c.-à-d. Que vous ne voulez pas PUT ou DELETE. , etc).

Contrairement à certains commentaires, j’ai également été incapable d’utiliser les deux attributs [HttpGet, HttpPost] en même temps, mais a pu spécifier les deux verbes à la place.

Actes

    private ActionResult testResult(int id)
    {
        return Json(new {
                            // user input
                            input = id,
                            // just so there's different content in the response
                            when = DateTime.Now,
                            // type of request
                            req = this.Request.HttpMethod,
                            // differentiate calls in response, for matching up
                            call = new StackTrace().GetFrame(1).GetMethod().Name
                        },
                        JsonRequestBehavior.AllowGet);
    }
    public ActionResult Test(int id)
    {
        return testResult(id);
    }
    [HttpGet]
    public ActionResult TestGetOnly(int id)
    {
        return testResult(id);
    }
    [HttpPost]
    public ActionResult TestPostOnly(int id)
    {
        return testResult(id);
    }
    [HttpPost, HttpGet]
    public ActionResult TestBoth(int id)
    {
        return testResult(id);
    }
    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    public ActionResult TestVerbs(int id)
    {
        return testResult(id);
    }

Résultats

via POSTMAN, mise en forme par markdowntables

| Method    | URL                   | Response                                                                                  |
|--------   |---------------------- |----------------------------------------------------------------------------------------   |
| GET       | /ctrl/test/5          | { "input": 5, "when": "/Date(1408041216116)/", "req": "GET", "call": "Test" }             |
| POST      | /ctrl/test/5          | { "input": 5, "when": "/Date(1408041227561)/", "req": "POST", "call": "Test" }            |
| PUT       | /ctrl/test/5          | { "input": 5, "when": "/Date(1408041252646)/", "req": "PUT", "call": "Test" }             |
| GET       | /ctrl/testgetonly/5   | { "input": 5, "when": "/Date(1408041335907)/", "req": "GET", "call": "TestGetOnly" }      |
| POST      | /ctrl/testgetonly/5   | 404                                                                                       |
| PUT       | /ctrl/testgetonly/5   | 404                                                                                       |
| GET       | /ctrl/TestPostOnly/5  | 404                                                                                       |
| POST      | /ctrl/TestPostOnly/5  | { "input": 5, "when": "/Date(1408041464096)/", "req": "POST", "call": "TestPostOnly" }    |
| PUT       | /ctrl/TestPostOnly/5  | 404                                                                                       |
| GET       | /ctrl/TestBoth/5      | 404                                                                                       |
| POST      | /ctrl/TestBoth/5      | 404                                                                                       |
| PUT       | /ctrl/TestBoth/5      | 404                                                                                       |
| GET       | /ctrl/TestVerbs/5     | { "input": 5, "when": "/Date(1408041709606)/", "req": "GET", "call": "TestVerbs" }        |
| POST      | /ctrl/TestVerbs/5     | { "input": 5, "when": "/Date(1408041831549)/", "req": "POST", "call": "TestVerbs" }       |
| PUT       | /ctrl/TestVerbs/5     | 404                                                                                       |
21
drzaus

Dans MVV 4, vous pouvez utiliser AcceptVerbsAttribute, je pense que c'est une solution très propre

[AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
public IHttpActionResult Login()
{
   // Login logic
}
8
Ben Anderson

Vous ne pouvez pas combiner cela à des attributs.

Mais vous pouvez mettre les deux sur une méthode d’action mais vous pouvez encapsuler votre logique dans une autre méthode et appeler cette méthode à partir des deux actions.

L'attribut ActionName permet d'avoir 2 ActionMethods avec le même nom.

[HttpGet]
public ActionResult MyMethod()
{
    return MyMethodHandler();
}

[HttpPost]
[ActionName("MyMethod")]
public ActionResult MyMethodPost()
{
    return MyMethodHandler();
}

private ActionResult MyMethodHandler()
{
    // handle the get or post request
    return View("MyMethod");
}
5
dknaack