Làm thế nào để bạn chuyển hướng đến một trang bằng cách sử dụng động từ POST?


131

Khi bạn gọi RedirectToActiontrong bộ điều khiển, nó sẽ tự động chuyển hướng bằng cách sử dụng HTTP GET. Làm thế nào để tôi nói rõ ràng để sử dụng HTTP POST?

Tôi có một hành động chấp nhận cả yêu cầu GET và POST và tôi muốn có thể RedirectToActionsử dụng POST và gửi cho nó một số giá trị.

Như thế này:

this.RedirectToAction(
    "actionname",
    new RouteValueDictionary(new { someValue = 2, anotherValue = "text" })
);

Tôi muốn someValueanotherValuecác giá trị được gửi bằng cách sử dụng HTTP POST thay vì GET. Có ai biết cách để làm điều này không?


Câu trả lời được đăng bởi jason sẽ hoạt động trong hầu hết các kịch bản, vấn đề duy nhất mà tôi thấy là nó dễ bị tai nạn. tức là Gọi một phương thức hành động trực tiếp bỏ qua tất cả các bộ lọc được áp dụng cho hành động. Vì vậy, trong trường hợp có bất kỳ loại bộ lọc xác thực hoặc bộ đếm nào được áp dụng cho phương thức hành động, dữ liệu đó có thể bị mất. Gọi một phương thức hành động trực tiếp sẽ hoạt động, nhưng nó nên được áp dụng cẩn thận.
amarnath chatterjee

Câu trả lời:


103

HTTP không hỗ trợ chuyển hướng đến một trang bằng POST. Khi bạn chuyển hướng ở đâu đó, tiêu đề "Vị trí" HTTP sẽ cho trình duyệt biết nơi cần đến và trình duyệt đưa ra yêu cầu GET cho trang đó. Có lẽ bạn sẽ chỉ cần viết mã cho trang của mình để chấp nhận các yêu cầu GET cũng như các yêu cầu POST.


4
Tò mò tại sao câu trả lời của tôi không được chấp nhận, tôi nghĩ rằng lời nói của tôi là âm thanh. :) Sau đó, một lần nữa, tôi có thể hơi thiên vị về nó ...
Jason Bunting

14
Trong khi câu trả lời này về cơ bản là chính xác, nó không đầy đủ. Xem câu trả lời của Jason Bunting dưới đây để có cách giải quyết tốt hơn nhiều.
Adrian Grigore

160

Đối với ví dụ cụ thể của bạn, tôi sẽ chỉ làm điều này, vì rõ ràng bạn không quan tâm đến việc thực sự trình duyệt có được chuyển hướng hay không (bằng cách chấp nhận câu trả lời bạn đã chấp nhận):

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index() {
   // obviously these values might come from somewhere non-trivial
   return Index(2, "text");
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int someValue, string anotherValue) {
   // would probably do something non-trivial here with the param values
   return View();
}

Điều đó hoạt động dễ dàng và không có hoạt động kinh doanh hài hước nào thực sự diễn ra - điều này cho phép bạn duy trì thực tế rằng điều thứ hai thực sự chỉ chấp nhận các yêu cầu POST HTTP (ngoại trừ trong trường hợp này, dù sao bạn cũng nằm trong tầm kiểm soát của bạn) và bạn không phải sử dụng TempData, đó là những gì liên kết bạn đã đăng trong câu trả lời của bạn đang gợi ý.

Tôi rất muốn biết điều gì là "sai" với điều này, nếu có bất cứ điều gì. Rõ ràng, nếu bạn thực sự muốn gửi đến trình duyệt một chuyển hướng, điều này sẽ không hoạt động, nhưng sau đó bạn nên hỏi tại sao bạn sẽ cố gắng chuyển đổi bất kể điều đó, vì nó có vẻ kỳ lạ đối với tôi.

Mong rằng sẽ giúp.


7
Ai biết tại sao bạn bị hạ bệ. Đây là một phương pháp rất hữu ích.
Peter J

2
Đây là cách tôi luôn luôn giải quyết vấn đề này là tốt. Hạ thấp điều này không có ý nghĩa.
Adrian Grigore

39
Tôi đã bỏ phiếu, mặc dù tôi không đồng ý với việc gọi mọi người là ngốc khi bạn không biết họ.
Jim Schubert

3
Tôi không phải là người xuống, nhưng một lưu ý với điều này là nếu bạn gọi một chế độ xem với một tên khác hoặc nếu các tham số quan trọng, chúng sẽ bị mất. Lý do là URL sẽ phản ánh các tham số hành động + trước khi chuyển hướng phía máy chủ. Điều này có thể dẫn đến sự nhầm lẫn của người dùng, đặc biệt nếu họ làm mới trang và sau đó tìm thấy chính họ ở trang trước (vì làm mới đã sử dụng URL cũ). Kỹ thuật này về cơ bản rất giống với Server.Transfer của asp.net, và các cảnh báo tương tự nên được thực hiện.
AaronLS

15
Tôi đã không downvote mỗi se nhưng tôi có thể thấy lý do. Phương pháp này vi phạm quy ước mã hóa được thiết lập bởi mẫu MVC. Nó chỉ hoạt động khi gọi hành động tương tự. Nếu hành động là một hành động khác, ngay cả trên cùng một bộ điều khiển, các giá trị định tuyến bị vặn và chế độ xem sai sẽ được trả về. Tóm lại: Đừng làm điều này.
erlando

21

Nếu bạn muốn truyền dữ liệu giữa hai hành động trong khi chuyển hướng mà không bao gồm bất kỳ dữ liệu nào trong chuỗi truy vấn, hãy đặt mô hình vào đối tượng TempData.

HOẠT ĐỘNG

TempData["datacontainer"] = modelData;

LƯỢT XEM

var modelData= TempData["datacontainer"] as ModelDataType; 

TempData có nghĩa là một ví dụ rất ngắn và bạn chỉ nên sử dụng nó trong các yêu cầu hiện tại và các yêu cầu tiếp theo! Vì TempData hoạt động theo cách này, bạn cần biết chắc chắn yêu cầu tiếp theo sẽ là gì và chuyển hướng sang chế độ xem khác là lần duy nhất bạn có thể đảm bảo điều này.

Do đó, kịch bản duy nhất sử dụng TempData sẽ hoạt động đáng tin cậy là khi bạn chuyển hướng.


11

thử cái này

return Content("<form action='actionname' id='frmTest' method='post'><input type='hidden' name='someValue' value='" + someValue + "' /><input type='hidden' name='anotherValue' value='" + anotherValue + "' /></form><script>document.getElementById('frmTest').submit();</script>");

2
Ghét nhưng yêu nó :)
divinci

Một hack như vậy nhưng đó là cách duy nhất tôi có thể làm những gì tôi muốn mà không vi phạm DRY hoặc tua lại toàn bộ thiết lập của tôi! Cảm ơn!
jamheadart

6

Tôi muốn mở rộng câu trả lời của Jason Bunting

như thế này

ActionResult action = new SampelController().Index(2, "text");
return action;

Và Eli sẽ ở đây để có ý tưởng về cách biến nó thành biến chung

Có thể nhận được tất cả các loại điều khiể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.