用于Action的MVC

我正在使用MVC C#。

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

[HttpPost/HttpGet] 

一个行动。 一个活跃的人怎么能有两个 – 实际用途是什么?

假设您有一个Login操作,它为用户提供一个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只是将操作限制为适用的请求types。

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

结果

通过邮递员,由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,我认为这是一个非常干净的解决scheme

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