Я использую MVC С#.
Может ли кто-нибудь привести пример того, почему нужно использовать
[HttpPost/HttpGet]
для действия. Как активный может иметь и то, и другое - что практическое применение?
Я использую MVC С#.
Может ли кто-нибудь привести пример того, почему нужно использовать
[HttpPost/HttpGet]
для действия. Как активный может иметь и то, и другое - что практическое применение?
Скажем, у вас есть действие 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)]
.
Вам не нужно указывать оба одновременно, если только вы не ограничиваете другие глаголы (т.е. вы не хотите 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 |
В Mvc 4 вы можете использовать AcceptVerbsAttribute, я думаю, что это очень чистое решение
[AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
public IHttpActionResult Login()
{
// Login logic
}
Вы не можете комбинировать это с атрибутами.
Но вы можете поместить оба метода одного действия, но вы можете инкапсулировать свои логики в другой метод и вызывать этот метод из обоих действий.
Атрибут 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");
}