Cách RedirectToAction trong ASP.NET MVC mà không mất dữ liệu yêu cầu


123

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 .

Một tình huống như vậy là khi bạn gặp phải lỗi xác thực sau khi gửi biểu mẫu và cần chuyển hướng quay 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.

Vì tôi yêu cầu biểu mẫu phải chứa POSTdữ liệu ed ban đầu , để 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 tôi có thể truyền dữ liệu qua RedirectToAction()? Nếu tôi sử dụng tham số viewData, POSTcác tham số của tôi sẽ được thay đổi thành GETtham số.


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

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

Câu trả lời:


81

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 hành động "Biểu mẫu" 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 bằng MVCv2, bạn có đang sử dụng MVCv3 không?
ChrisAnnODell

1
Đây là tiền MVC1 (2008). Lambdas đã bị xóa ở 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 trợ giúp của chúng ở giai đoạn đó: stackoverflow.com/questions/1936/, ). Trong mvc2, bạn sẽ có thể truy cập RedirectToAction ("Biểu mẫu"), tức là đặt tên dưới dạng 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.
Matt Mitchell

37

Hãy nhớ rằng TempData lưu trữ bộ sưu tập biểu mẫu 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 sự thật (thông qua đo lường và định hình) rằng việc sử dụng trạng thái Phiên đang làm tổn thương bạn.


13

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

using MvcContrib.Filters;

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

8

Có một cách khác để tránh tempdata. Mẫu tôi thích liên quan đến việc tạo 1 hành động cho cả kết xuất ban đầu và kết xuất lại của biểu mẫu không hợp lệ. Nó đi một cái gì đó như thế này:

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ô hình ít nhiều. Một giả nhỏ. Với điều này, bạn có thể tạo 1 chế độ xem để 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 điền với các giá trị trước đó) và hiển thị thông báo lỗi.

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

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


Tôi cũng sử dụng TempData, vấn đề mà 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 dữ liệu biểu mẫu" không. Sử dụng giải pháp TempData như MattMitchell đã loại bỏ vấn đề này.
dùng10479

Mát mẻ. Có vẻ ai đó cũng nhận thấy ý tưởng cơ bản này với bản xem trước 5.
Matt Mitchell

2

Nếu bạn muốn truyền dữ liệu cho hành động được chuyển hướng, phương pháp 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);

0

TempData là giải pháp giữ dữ liệu từ hành động này sang hành động khác.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
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.