2012-10-22 14 views
10

は、ここで私がやろうとしているものです:URLを汚染することなくモデルオブジェクトをRedirectToActionに渡すか?

public ActionResult Index() 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return RedirectToAction("Gracias", model); 
    } 

    return View(model); 
} 

public ActionResult Gracias(ContactModel model) 
{ 
    return View(model); 
} 

すべての3つのアクションメソッドは、同じコントローラです。基本的には、ユーザーが連絡先フォームにデータを入力し、Modelオブジェクトの名前を使用して感謝のページにリダイレクトしたいとします。

コードは動作しますが、URLはGET変数とともに渡されます。理想的ではない。

http://localhost:7807/Contacto/Gracias?Nombre=Sergio&Apellidos=Tapia&Correo=opiasdf&Telefono=oinqwef&Direccion=oinqef&Pais=oinqwef&Mensaje=oinqwef 

お勧めはありますか?

答えて

24

TempDataの解決策のようなサウンドです!

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
    // Send email using Model information. 
    TempData["model"] = model; 
    return RedirectToAction("Gracias"); 
    } 

    return View(model); 
} 

public ActionResult Gracias() 
{ 
    ContactModel model = (ContactModel)TempData["model"]; 
    return View(model); 
} 
+0

に型付けされます。 TIL。ありがとう! – sergserg

+1

それらがシリアライズ可能である限り! TempDataはセッションに格納され、Serializableオブジェクト/クラスのみが使用できます。 –

+2

Tempのデータはここではうまくいくかもしれませんが、インデックスから直接 "Gracias"ビューを表示するだけではありません(モデルはすでにスコープ内にあります)。あなたは本質的に役に立たないリダイレクトである自分のサーバーラウンドトリップも保存します。 –

0

迅速な答えは、モデル全体が、あなたがリポジトリからモデルを取得するために使用できるいくつかの識別子を渡さないで:

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return RedirectToAction("Gracias", model.ID); 
    } 

    return View(model); 
} 

public ActionResult Gracias(int contactID) 
{ 
    ContactModel model = new ContractRepository().GetContact(contactID); 
    return View(model); 
} 
+0

これは、あなたがそう考える方法では機能しません。 'HttpPost Index()'メソッドで更新されたモデルを渡すと、 'Gracias()'メソッドのすべての値がユーザではなくデータベースからのものであるため、これらの変更はすべて失われます。 –

0

代わりの

return RedirectToAction("Gracias", model); 

をやってすることができます

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return View("Gracias", model); 
    } 

    return View(model); 
} 

を実行し、Graciasコントローラの操作を削除します。上記の "Gracias"ビューを使用すると、ContactModelモデルが表示されます。

同じモデルを使用していて、ワークフローのロックステップの一部である場合、別のコントローラアクションを持つ必要はありません。 "成功したインデックスのPOSTは、常にGracias Viewが表示されるようになります。

また、モデルをTempDataに保存することもできますが、これは1セッションのリクエストのようなものですが、あなたの状況はちょうど事を複雑にするように

思考?

+0

URLは 'http:// localhost:7807/Contacto/Index'のように見えますが、これが受け入れられるなら、これが最も簡単な方法です。 –

+0

それは受け入れられないので、私はこのルートに行かなかったのです。 – sergserg

+0

他の時に誰かが "http:// localhost:7807/Contacto/Gracias"にヒットしないように(または、それらが戻るボタンを押してページがキャッシュされていないと)空のフィールドとおそらくあなたのビューがどのように見えるかに応じて例外があります。別のURLを実際に表示したくないかもしれないと考えてください。 –

0

リダイレクトなしで簡単にできないのでしょうか?

は、ここで私が持っているものです。

[HttpGet] 
    public ActionResult Contact() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Contact(EmailResponse response) 
    { 
     if(ModelState.IsValid){ 
      return View("Thanks", response); 
     } 
     else 
     { 
      return View(); 
     } 
    } 

"Thanks"ビューが強く、私はあなたがTempDataを辞書に複合型を救うことができる全く分からなかったEmailResponse

関連する問題