2012-03-04 40 views
65

Tại sao lại không chính xác?Phương thức GET và POST có cùng tên Hành động trong cùng một Bộ điều khiển

{ 
    public class HomeController : Controller 
    { 

     [HttpGet] 
     public ActionResult Index() 
     { 
      Some Code--Some Code---Some Code 
      return View(); 
     } 

     [HttpPost] 
     public ActionResult Index() 
     { 
      Some Code--Some Code---Some Code 
      return View(); 
     } 

    } 

Làm cách nào để người kiểm soát có thể trả lời một điều khi được "đăng" và một khi được "đăng"?

Trả lời

130

Vì bạn không thể có hai phương pháp có cùng tên và chữ ký bạn phải sử dụng ActionName thuộc tính:

[HttpGet] 
    public ActionResult Index() 
    { 
     Some Code--Some Code---Some Code 
     return View(); 
    } 

    [HttpPost] 
    [ActionName("Index")] 
    public ActionResult IndexPost() 
    { 
     Some Code--Some Code---Some Code 
     return View(); 
    } 

Xem thêm "How a Method Becomes An Action"

+0

tôi biết đã quá muộn để hỏi. nhưng có thể có hai phương thức hành động HttpPost khác nhau với cùng tên có các tham số khác nhau không. Tôi đang nói về một trường hợp mà tôi cần phải áp dụng các bộ lọc cho một phương thức tạo mà đã có phương thức HttpPost được định nghĩa – Vini

+0

Có, có thể vì nó là một chữ ký phương thức .Net hợp lệ. Các phương thức bị quá tải (Phương thức quá tải). – nwolisa

2

Không thể đa hành động cùng tên và cùng tham số

[HttpGet] 
    public ActionResult Index() 
    { 
     return View(); 
    } 
    [HttpPost] 
    public ActionResult Index(int id) 
    { 
     return View(); 
    } 

ID mặc định int không được sử dụng

+1

Nó sẽ thực sự hoạt động nếu id là một int không nullable? – jahu

5

Để trả lời câu hỏi cụ thể của bạn, bạn không thể có hai phương thức có cùng tên và cùng một đối số trong một lớp; sử dụng các thuộc tính HttpGet và HttpPost không phân biệt các phương thức.

Để giải quyết điều này, tôi muốn thường bao gồm các mô hình điểm cho các mẫu bạn đang đăng:

public class HomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    { 
     Some Code--Some Code---Some Code 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(formViewModel model) 
    { 
     do work on model -- 
     return View(); 
    } 

} 
32

Trong khi ASP.NET MVC sẽ cho phép bạn có hai hành động có cùng tên, .NET sẽ không cho phép bạn có hai phương thức có cùng chữ ký - tức là cùng tên và thông số.

Bạn sẽ cần phải đặt tên cho các phương thức khác nhau sử dụng thuộc tính ActionName để cho ASP.NET MVC biết rằng chúng thực sự là cùng một hành động.

Điều đó nói rằng, nếu bạn đang nói về GET và POST, vấn đề này có thể sẽ biến mất, vì hành động POST sẽ có nhiều tham số hơn GET và do đó có thể phân biệt được.

Vì vậy, bạn cần một trong hai:

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost, ActionName("ActionName")] 
public ActionResult ActionNamePost() {...} 

Hoặc,

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost] 
public ActionResult ActionName(string aParameter) {...} 
2

Bạn không thể có nhiều hành động cùng tên. Bạn có thể thêm tham số vào một phương thức và phương thức đó sẽ hợp lệ. Ví dụ:

public ActionResult Index(int i) 
    { 
     Some Code--Some Code---Some Code 
     return View(); 
    } 

Có một số cách để thực hiện hành động chỉ khác với động từ yêu cầu. Tôi yêu thích và, tôi nghĩ, dễ nhất để thực hiện là sử dụng gói AttributeRouting. Sau khi cài đặt, chỉ cần thêm thuộc tính vào phương pháp của bạn như sau:

[GET("Resources")] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [POST("Resources")] 
    public ActionResult Create() 
    { 
     return RedirectToAction("Index"); 
    } 

Trong ví dụ trên, các phương thức có tên khác nhau nhưng tên hành động trong cả hai trường hợp là "Tài nguyên". Sự khác biệt duy nhất là động từ yêu cầu.

Các gói phần mềm có thể được cài đặt bằng NuGet như thế này:

PM> Install-Package AttributeRouting

Nếu bạn không muốn phụ thuộc vào các gói AttributeRouting bạn có thể làm điều này bằng cách viết một selector hành động tùy chỉnh thuộc tính.

12

Tôi muốn chấp nhận một bài đăng biểu mẫu cho các hành động POST của tôi, ngay cả khi tôi không cần nó. Đối với tôi, nó chỉ cảm thấy giống như điều đúng đắn để làm khi bạn được cho là đang đăng một cái gì đó.

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     //Code... 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(FormCollection form) 
    { 
     //Code... 
     return View(); 
    } 
} 
+0

giải thích đơn giản tuyệt vời – Ali

+1

Chỉ có vấn đề là điều này gây ra HttpRequestValidationException thổi ngay cả khi [AllowHtml] vv Không phải là nó là một ngoại lệ xấu, nhưng thực hiện của nó, và khi nó được kích hoạt (và đặc biệt là khi nó được kích hoạt trong một khu vực) là không cần thiết mờ mịt. – Ted

1

Bạn nhận được câu trả lời hay cho câu hỏi này nhưng tôi muốn thêm hai xu của mình. Bạn có thể sử dụng một phương pháp và yêu cầu xử lý theo loại yêu cầu:

public ActionResult Index() 
{ 
    if("GET"==this.HttpContext.Request.RequestType) 
    { 
     Some Code--Some Code---Some Code for GET 
    } 
    else if("POST"==this.HttpContext.Request.RequestType) 
    { 
     Some Code--Some Code---Some Code for POST 
    } 
    else 
    { 
     //exception 
    } 

    return View(); 
} 
Các vấn đề liên quan