MVC [HttpPost/HttpGet] for Action
我正在使用MVC C#。
有人可以举例说明为什么要使用
1 | [HttpPost/HttpGet] |
操作。主动者如何兼具两者-实际用途是什么?
假设您有一个
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(); } |
如果您的操作服务于多个动词的请求,您还可以组合请求方法属性:
您无需同时指定两个动词,除非您专门限制其他动词(即您不希望输入或删除等)。
与某些注释相反,我也无法同时使用两个属性
动作
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 } |
您无法将其组合为属性。
但是您可以将两种方法都放在一个方法上,但是可以封装您的方法
逻辑转换为另一个方法,并从两个动作中调用此方法。
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"); } |