Phương thức GET và POST có cùng tên Hành động trong cùng Bộ điều khiển [trùng lặp]


78

Tại sao điều này không chính xác?

{
    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 thế nào tôi có thể yêu cầu một bộ điều khiển trả lời một câu khi nào là "getted" và một khi được "đăng"?

Câu trả lời:


176

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

[HttpGet]
public ActionResult Index()
{
  // your code
  return View();
}

[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost()
{
  // your code
  return View();
}

Cũng xem "Cách một phương pháp trở thành một hành động"


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

Có, có thể vì nó là chữ ký phương thức .Net hợp lệ. Các phương thức được nạp chồng (Phương thức nạp chồng).
nwolisa 13/1217

37

Trong khi ASP.NET MVC sẽ cho phép bạn có hai hành động với cùng một 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à các tham số.

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

Điều đó có nghĩa là, 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:

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

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

Hoặc là,

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

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

1
Ví dụ: Xóa hành động cho cả GET và POST yêu cầu Id. NHẬN để xem dữ liệu và ĐĂNG để xóa nó. Trong trường hợp đó tôi sẽ cần phải sử dụng ActionName
Xeuron

17

Tôi muốn chấp nhận một bài đăng trên biểu mẫu cho các hành động ĐĂNG của mình, ngay cả khi tôi không cần nó. Đối với tôi, nó giống như một điều đúng đắn để làm khi bạn được cho là đă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();
    }
}

1
Chỉ có một vấn đề là điều này kích hoạt HttpRequestValidationException bị nổ tung ngay cả khi [AllowHtml], v.v. Không phải đó là một ngoại lệ tồi, nhưng việc triển khai 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 rõ ràng một cách không cần thiết.
Ted

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ác đối số giống nhau 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 pháp.

Để giải quyết vấn đề này, tôi thường bao gồm mô hình chế độ xem cho biểu 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();
    }

}

3

Bạn đã nhận được câu trả lời tốt 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à xử lý yêu cầu 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();
}

2

Không thể thực hiện nhiều hành động cùng tên và cùng một thông số

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

mặc dù int id không được sử dụng


2

Bạn không thể có nhiều hành động với cùng một tên. Bạn có thể thêm một tham số vào một phương thức và điều đó 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 cần làm để có các hành động chỉ khác nhau ở động từ yêu cầu. Tôi yêu thích và tôi nghĩ, cách dễ thực hiện nhất là sử dụng gói AttributeRouting . Sau khi cài đặt, chỉ cần thêm một thuộc tính vào phương thức 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.

Gói có thể được cài đặt bằng NuGet như sau:

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ể thực hiện việc này bằng cách viết thuộc tính bộ chọn hành động tùy chỉnh.


0

Hôm nay tôi đã kiểm tra một số tài nguyên về câu hỏi tương tự và tôi nhận được một ví dụ rất thú vị.

Có thể gọi cùng một phương thức bằng giao thức GET và POST, nhưng bạn cần quá tải các tham số như sau:

@using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { @id = "form-consulta" }))
{
//code
}

Hành động:

[ActionName("Index")]
public async Task<ActionResult> IndexAsync(MyModel model)
{
//code
}

Theo mặc định, một phương thức không có giao thức rõ ràng là GET, nhưng trong trường hợp đó, có một tham số được khai báo cho phép phương thức hoạt động giống như một POST.

Khi GET được thực thi, tham số không quan trọng, nhưng khi POST được thực thi, tham số là bắt buộc theo yêu cầu của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.