Подтвердить что ты не робот

MVC [HttpPost/HttpGet] для действия

Я использую MVC С#.

Может ли кто-нибудь привести пример того, почему нужно использовать

[HttpPost/HttpGet] 

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

4b9b3361

Ответ 1

Скажем, у вас есть действие Login, которое предоставляет пользователю экран входа в систему, а затем возвращает имя пользователя и пароль после отправки пользователем формы:

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

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

MVC не получает четких инструкций о том, какое действие есть, хотя мы можем сказать, посмотрев на него. Если вы добавите [HttpGet] к первому действию и [HttpPost] в действие раздела, MVC четко знает, какое действие является тем, что.

Почему? См. Методы запроса. Длинные и короткие: когда пользователь просматривает страницу, это запрос GET и когда пользователь отправляет форму, обычно это запрос POST. HttpGet и HttpPost просто ограничивают действие применимым типом запроса.

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

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

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

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

Ответ 2

Вам не нужно указывать оба одновременно, если только вы не ограничиваете другие глаголы (т.е. вы не хотите PUT или DELETE и т.д.).

В отличие от некоторых комментариев, я также не мог одновременно использовать оба атрибута [HttpGet, HttpPost], но мог указать оба глагола.

Действия

    private ActionResult testResult(int id)
    {
        return Json(new {
                            // user input
                            input = id,
                            // just so there 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);
    }

Результаты

через POSTMAN, форматирование 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                                                                                       |

Ответ 3

В Mvc 4 вы можете использовать AcceptVerbsAttribute, я думаю, что это очень чистое решение

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

Ответ 4

Вы не можете комбинировать это с атрибутами.

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

Атрибут ActionName позволяет иметь 2 ActionMethods с тем же именем.

[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");
}