2008-08-05 29 views
113

Sử dụng ASP.NET MVC có các tình huống (chẳng hạn như gửi biểu mẫu) có thể yêu cầu RedirectToAction.Cách RedirectToAction trong ASP.NET MVC mà không làm mất dữ liệu yêu cầu

Một trường hợp như vậy là khi bạn gặp lỗi xác thực sau khi gửi biểu mẫu và cần chuyển hướng trở lại biểu mẫu, nhưng muốn URL phản ánh URL của biểu mẫu chứ không phải trang hành động mà nó gửi đến.

Vì tôi yêu cầu biểu mẫu chứa dữ liệu ban đầu POST, để thuận tiện cho người dùng cũng như mục đích xác thực, làm cách nào để chuyển dữ liệu qua RedirectToAction()? Nếu tôi sử dụng thông số viewData, thông số POST của tôi sẽ được thay đổi thành thông số GET.

+0

Dưới đây là một câu hỏi mà tương tự (trên cùng một chủ đề), nhưng khác với cái này. Dù sao, nó vẫn có thể được quan tâm đến những người quan tâm đến câu hỏi này: [http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get](http:/ /stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get) –

+0

Tại sao bạn không quay trở lại cùng một chế độ xem nếu có lỗi? RedirectToAction thường được gọi nếu Model là hợp lệ - hoặc tôi thiếu một cái gì đó ?! – niico

Trả lời

76

Giải pháp là sử dụng thuộc tính TempData để lưu trữ các thành phần Yêu cầu mong muốn.

Ví dụ:

public ActionResult Send() 
{ 
    TempData["form"] = Request.Form; 
    return this.RedirectToAction(a => a.Form()); 
} 

Sau đó, trong "Mẫu" hành động của bạn, bạn có thể đi:

public ActionResult Form() 
{ 
    /* Declare viewData etc. */ 

    if (TempData["form"] != null) 
    { 
     /* Cast TempData["form"] to 
     System.Collections.Specialized.NameValueCollection 
     and use it */ 
    } 

    return View("Form", viewData); 
} 
+1

RedirectToAction (a => a.Form()) không biên dịch cho tôi sử dụng MVCv2, bạn đang sử dụng MVCv3? – ChrisAnnODell

+1

Đây là trước MVC1 (2008). Các lambdas đã được gỡ bỏ ở một số giai đoạn tôi tin (có một dự án codeplex MVCContrib giới thiệu lại chúng, mặc dù bạn cũng có thể sử dụng thuộc tính helper của chúng ở giai đoạn đó: http: // stackoverflow.com/questions/1936/how-to-redirecttoaction-in-asp-net-mvc-không-mất-yêu cầu-dữ liệu/718653 # 718653). Trong mvc2 bạn sẽ có thể chuyển RedirectToAction ("Form"), tức là tên như một chuỗi, mặc dù tôi nhớ lại rằng MVC 2 hoặc 3 đã giới thiệu một thuộc tính trợ giúp tương tự như trong MVCContrib nếu bạn muốn tìm kiếm. –

36

Hãy ghi nhớ rằng TempData cửa hàng bộ sưu tập hình thức trong phiên. Nếu bạn không thích hành vi đó, bạn có thể triển khai giao diện ITempDataProvider mới và sử dụng một số cơ chế khác để lưu trữ dữ liệu tạm thời. Tôi sẽ không làm điều đó trừ khi bạn biết một thực tế (thông qua đo lường và lược tả) rằng việc sử dụng trạng thái Phiên làm tổn thương bạn.

8

Có một cách khác để tránh tempdata. Mẫu mà tôi thích bao gồm việc tạo 1 hành động cho cả lần hiển thị gốc và hiển thị lại biểu mẫu không hợp lệ. Nó có dạng như sau:

var form = new FooForm(); 

if (request.UrlReferrer == request.Url) 
{ 
    // Fill form with previous request's data 
} 

if (Request.IsPost()) 
{ 
    if (!form.IsValid) 
    { 
     ViewData["ValidationErrors"] = ... 
    } else { 
     // update model 
     model.something = foo.something; 
     // handoff to post update action 
     return RedirectToAction("ModelUpdated", ... etc); 
    } 
} 

// By default render 1 view until form is a valid post 
ViewData["Form"] = form; 
return View(); 

Đó là mẫu nhiều hơn hoặc ít hơn. Một pseudoy nhỏ. Với điều này, bạn có thể tạo 1 khung nhìn để xử lý hiển thị biểu mẫu, hiển thị lại các giá trị (vì biểu mẫu sẽ được lấp đầy với các giá trị trước đó) và hiển thị các thông báo lỗi.

Khi đăng bài lên hành động này, nếu nó hợp lệ, nó chuyển quyền kiểm soát sang một hành động khác.

Tôi đang cố gắng làm cho mẫu này dễ dàng trong số .net validation framework khi chúng tôi xây dựng hỗ trợ cho MVC.

+0

Tuyệt. Có vẻ ai đó đã nhận thấy ý tưởng cơ bản này với bản xem trước 5 quá. –

+0

Tôi cũng sử dụng TempData, vấn đề như tôi hiểu, với giải pháp của bạn Deeno là nếu người dùng làm mới trang sau khi đăng dữ liệu không hợp lệ, họ sẽ nhận được xác nhận "Bạn có muốn gửi lại biểu mẫu dữ liệu" không. Sử dụng các giải pháp TempData như MattMitchell nói loại bỏ vấn đề này. – user10479

13

Hãy xem MVCContrib, bạn có thể làm điều này:

using MvcContrib.Filters; 

[ModelStateToTempData] 
public class MyController : Controller { 
    // 
    ... 
} 
2

Nếu bạn muốn để truyền dữ liệu đến các hành động chuyển hướng, phương pháp mà bạn có thể sử dụng là:

return RedirectToAction("ModelUpdated", new {id = 1}); 
// The definition of the action method like public ActionResult ModelUpdated(int id); 
Các vấn đề liên quan