【问题标题】:MVC [HttpPost/HttpGet] for ActionMVC [HttpPost/HttpGet] 用于操作
【发布时间】:2012-07-30 20:39:14
【问题描述】:

我正在使用 MVC C#。

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

[HttpPost/HttpGet] 

对于一个动作。一个主动者怎么能两者兼得——有什么实际用途?

【问题讨论】:

    标签: asp.net-mvc model-view-controller


    【解决方案1】:

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

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

    MVC 没有得到明确的指示,说明哪个动作是哪个动作,尽管我们可以通过查看它来判断。如果将 [HttpGet] 添加到第一个动作,将 [HttpPost] 添加到部分动作,MVC 清楚地知道哪个动作是哪个。

    为什么?见Request Methods。长短:当用户查看页面时,这是一个 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)].

    【讨论】:

    • 感谢您的回答。我明白你在说什么,并已相应地使用它。从网上的一些阅读中,我的印象是我们可以将 [HttpGet] 和 [HttpPost] 用于相同的操作(不分开)
    • 刚刚在 MVC4 上试过。 [HttpGet][HttpPost] 不起作用,它只接受 GET 请求(或任何先写的动词)。但是,[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] 效果很好。
    • @AndreasLarsen:也许考虑专门发布一个关于此的问题,以便 MS 可以看到它。如果我能得到确认,我会编辑我的答案。
    • 我可以确认 AndreasLarsen 报告的内容。您必须使用 AcceptVerbs 在方法上有 2+ 个动词。
    • @Kivin 我已经在 MVC5 中测试了 [HttpGet, HttpPost] 并且它不适用于两个动词。 drzaus 的回答也证实它不起作用。 [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] 确实有效。
    【解决方案2】:

    您不需要同时指定两者,除非您特别限制 other 动词(即您不想要 PUT 或 DELETE 等)。

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

    动作

        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 格式化

    | 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 个同名的 ActionMethod。

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

      【讨论】:

      • 不确定“你不能将它与属性结合起来”是什么意思。意思是,但你可以组合属性,如另一个答案所示。
      • 我尝试将 [HttpGet, HttpPost] 添加到一个操作中,但这不仅适用于第一个属性,因此对我来说这个答案是正确的。
      • [AcceptVerbs(HttpVerbs.Post|HttpVerbs.Get)] 有效。刚试了一下。然而,在同一个动作上使用 [HttpGet] 和 [HttpPost] 似乎只适用于第一个动词。
      • 这不是错误的,因为它可以工作,但它是不必要的,因为 httppost 和 httpget 可以使用前面所示的 acceptvebs 组合
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2015-07-06
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      相关资源
      最近更新 更多