Bagaimana RedirectToAction di ASP.NET MVC tanpa kehilangan data permintaan

123

Menggunakan ASP.NET MVC ada situasi (seperti pengiriman formulir) yang mungkin memerlukan file RedirectToAction.

Salah satu situasi tersebut adalah ketika Anda menemukan kesalahan validasi setelah pengiriman formulir dan perlu dialihkan kembali ke formulir, tetapi ingin URL mencerminkan URL formulir, bukan halaman tindakan yang dikirimkannya.

Karena saya memerlukan formulir untuk memuat data asli POSTed, untuk kenyamanan pengguna, serta tujuan validasi, bagaimana saya bisa melewatkan data melalui RedirectToAction()? Jika saya menggunakan parameter viewData, POSTparameter saya akan diubah menjadi GETparameter.

Matt Mitchell
sumber
Berikut pertanyaan yang serupa (tentang topik yang sama), tetapi berbeda dari yang ini. Bagaimanapun, ini mungkin masih menarik bagi mereka yang tertarik dengan pertanyaan ini: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann
Mengapa Anda tidak mengembalikan tampilan yang sama jika ada kesalahan? RedirectToAction biasanya dipanggil jika Modelnya valid - atau saya melewatkan sesuatu ?!
niico

Jawaban:

81

Solusinya adalah dengan menggunakan properti TempData untuk menyimpan komponen Request yang diinginkan.

Misalnya:

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

Kemudian dalam tindakan "Formulir", Anda dapat pergi:

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);
}
Matt Mitchell
sumber
1
RedirectToAction (a => a.Form ()) tidak dikompilasi untuk saya menggunakan MVCv2, apakah Anda menggunakan MVCv3?
ChrisAnnODell
1
Ini adalah pra-MVC1 (2008). Lambda telah dihapus pada beberapa tahap saya percaya (ada proyek codeplex MVCContrib yang memperkenalkan mereka kembali, meskipun Anda juga dapat menggunakan atribut helper mereka pada tahap itu: stackoverflow.com/questions/1936/… ). Di mvc2 Anda harus bisa menggunakan RedirectToAction ("Form"), yaitu nama sebagai string, meskipun saya ingat bahwa MVC 2 atau 3 memperkenalkan atribut pembantu yang mirip dengan yang ada di MVCContrib jika Anda ingin mencari.
Matt Mitchell
37

Perlu diingat bahwa TempData menyimpan koleksi formulir dalam sesi. Jika Anda tidak menyukai perilaku itu, Anda dapat mengimplementasikan antarmuka ITempDataProvider baru dan menggunakan beberapa mekanisme lain untuk menyimpan data sementara. Saya tidak akan melakukan itu kecuali Anda tahu pasti (melalui pengukuran dan pembuatan profil) bahwa penggunaan status Sesi merugikan Anda.

Haacked
sumber
13

Lihatlah MVCContrib , Anda bisa melakukan ini:

using MvcContrib.Filters;

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

Ada cara lain untuk menghindari tempdata. Pola yang saya suka melibatkan pembuatan 1 tindakan untuk render asli dan render ulang dari bentuk yang tidak valid. Ini berjalan seperti ini:

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();

Itulah polanya kurang lebih. Seorang pseudoy kecil. Dengan ini Anda dapat membuat 1 tampilan untuk menangani rendering formulir, menampilkan ulang nilai (karena formulir akan diisi dengan nilai sebelumnya), dan menampilkan pesan kesalahan.

Ketika memposting ke tindakan ini, jika valid itu mentransfer kontrol ke tindakan lain.

Saya mencoba membuat pola ini mudah dalam kerangka validasi .net saat kami membangun dukungan untuk MVC.

Dane O'Connor
sumber
Saya juga menggunakan TempData, masalahnya seperti yang saya mengerti, dengan solusi Anda Deeno adalah jika pengguna menyegarkan halaman setelah memposting data yang tidak valid mereka akan menerima konfirmasi "Apakah Anda ingin mengirim ulang data formulir". Menggunakan solusi TempData seperti yang dikatakan MattMitchell menghilangkan masalah ini.
pengguna10479
Keren. Sepertinya seseorang memperhatikan ide dasar ini dengan pratinjau 5 juga.
Matt Mitchell
2

Jika Anda ingin meneruskan data ke tindakan yang diarahkan ulang, metode yang dapat Anda gunakan adalah:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);
lzlstyle.dll
sumber
0

TempData adalah solusi yang menjaga data dari aksi ke aksi.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Aswal
sumber