ASP.NET MVC'de istek verilerini kaybetmeden RedirectToAction nasıl yapılır


123

ASP.NET MVC kullanıldığında, .dll gerektirebilecek durumlar (form gönderme gibi) vardır RedirectToAction.

Böyle bir durum, bir form gönderildikten sonra doğrulama hatalarıyla karşılaştığınızda ve forma yeniden yönlendirmeniz gerektiğinde, ancak URL'nin gönderdiği eylem sayfasını değil formun URL'sini yansıtmasını istemenizdir.

Formun POST, kullanıcı rahatlığı ve doğrulama amacıyla orijinal olarak düzenlenmiş verileri içermesini zorunlu kıldığım için, verileri RedirectToAction()? Ben VIEWDATA parametresini kullanırsanız, benim POSTparametreleri değiştirilecektir GETparametreler.


İşte benzer (aynı konuda), ancak bundan farklı bir soru. Her neyse, bu soruyla ilgilenenler yine de ilgisini çekebilir: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann

Bir hata varsa neden aynı görüşe dönmüyorsunuz? RedirectToAction, genellikle Model geçerliyse çağrılır - yoksa bir şey mi eksik ?!
niico

Yanıtlar:


81

Çözüm, istenen Request bileşenlerini depolamak için TempData özelliğini kullanmaktır.

Örneğin:

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

Daha sonra "Form" işleminizde şunları yapabilirsiniz:

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 ()) MVCv2 kullanarak benim için derlenmiyor, MVCv3 kullanıyor musunuz?
ChrisAnnODell

1
Bu, MVC1 öncesiydi (2008). Lambdalar inandığım bir aşamada kaldırıldı (onları yeniden tanıtan bir codeplex projesi MVCContrib var, ancak bu aşamada yardımcı niteliklerini de kullanabilirsiniz: stackoverflow.com/questions/1936/… ). Mvc2'de RedirectToAction ("Form"), yani bir dizge olarak ad olarak gidebilirsiniz, ancak MVC 2 veya 3'ün, aramaya devam etmek istiyorsanız MVCContrib'e benzer bir yardımcı öznitelik sunduğunu gevşek bir şekilde hatırlıyorum.
Matt Mitchell

37

TempData'nın form koleksiyonunu oturumda sakladığını unutmayın. Bu davranışı beğenmezseniz, yeni ITempDataProvider arabirimini uygulayabilir ve geçici verileri depolamak için başka bir mekanizma kullanabilirsiniz. Oturum durumu kullanımının size zarar verdiğini (ölçüm ve profilleme yoluyla) bilmediğiniz sürece bunu yapmam.


13

MVCContrib'e bir göz atın , bunu yapabilirsiniz:

using MvcContrib.Filters;

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

8

Tempdata'dan kaçınmanın başka bir yolu var. Sevdiğim kalıp, hem orijinal oluşturma hem de geçersiz formun yeniden oluşturulması için 1 eylem oluşturmayı içerir. Şöyle bir şey oluyor:

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

Bu, aşağı yukarı modeldir. Biraz sahte. Bununla, formu oluşturmayı, değerleri yeniden görüntülemeyi (form önceki değerlerle doldurulacağından) ve hata mesajlarını gösteren 1 görünüm oluşturabilirsiniz.

Bu eyleme gönderme yapıldığında, geçerliyse kontrolü başka bir eyleme aktarır.

MVC için destek oluştururken .net doğrulama çerçevesinde bu kalıbı kolaylaştırmaya çalışıyorum .


Ben de TempData'yı kullanıyorum, anladığım kadarıyla sorun, Deeno çözümünüzle ilgili olarak, kullanıcının geçersiz verileri gönderdikten sonra sayfayı yenilemesi durumunda "Form verilerini yeniden göndermek ister misiniz" onayı alacak olmasıdır. MattMitchell'in söylediği gibi TempData çözümünü kullanmak bu sorunu ortadan kaldırır.
user10479

Güzel. Görünüşe göre birisi bu temel fikri 5. önizleme ile de fark etmiş.
Matt Mitchell

2

Verileri yeniden yönlendirilen eyleme geçirmek istiyorsanız, kullanabileceğiniz yöntem şudur:

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

0

TempData, verileri eylemden eyleme tutan çözümdür.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.