关于asp.net mvc:MVC [HttpPost / HttpGet]操作

MVC [HttpPost/HttpGet] for Action

我正在使用MVC C#。

有人可以举例说明为什么要使用

1
[HttpPost/HttpGet]

操作。主动者如何兼具两者-实际用途是什么?


假设您有一个Login操作,该操作为用户提供了登录屏幕,然后在用户提交表单后收到了用户名和密码:

1
2
3
4
5
6
7
8
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仅将操作限制为适用的请求类型。

1
2
3
4
5
6
7
8
9
10
[HttpGet]
public ActionResult Login() {
    return View();
}

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

如果您的操作服务于多个动词的请求,您还可以组合请求方法属性:

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


您无需同时指定两个动词,除非您专门限制其他动词(即您不希望输入或删除等)。

与某些注释相反,我也无法同时使用两个属性[HttpGet, HttpPost],但能够同时指定两个动词。

动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    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);
    }

结果

通过POSTMAN,按markdowntables格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 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,我认为这是一个非常干净的解决方案

1
2
3
4
5
[AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
public IHttpActionResult Login()
{
   // Login logic
}

您无法将其组合为属性。

但是您可以将两种方法都放在一个方法上,但是可以封装您的方法
逻辑转换为另一个方法,并从两个动作中调用此方法。

ActionName属性允许具有两个同名的ActionMethod。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[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");
}