2011-05-07 106 views
2

我有一個聯繫頁面,而這個頁面應由顯示窗體或成功消息或失敗消息,所以基本上是這樣的:與ASP.NET MVC聯繫頁3

@model MyApp.Models.ContactData 

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<div> 

...Some static content... 


If page was opened the first time 
    -> Render a form here 
Else If form was posted and data successfully processed 
    -> Render a success message here 
Else If form was posted but error occurred during processing 
    -> Render a failure message here 

...Some static content... 


</div> 

我不不知道用MVC 3實現這一點的最好方法是什麼?我是否創建了三個完全獨立的視圖(這是我想避免的,因爲靜態內容對於所有三個視圖都是相同的)?或者,我可以創建三個部分視圖,然後根據一個額外的標誌來決定我可以放入模型類中的部分視圖來渲染嗎?或者我可以從控制器動態注入局部視圖到視圖中?

控制器我到目前爲止是這樣的:

public class ContactController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(ContactData contactData) 
    { 
     if (ModelState.IsValid) 
     { 
      ContactService service = new ContactService(); 
      bool result = service.Process(contactData); 

      return ?; // What do I return now? It must somehow depend on result. 
     } 
     else 
      return View(contactData)); 
    } 

} 

我也有類似的頁面和行爲與ASP.NET WebForms和解決方案在那裏把標記的三可變塊爲asp:Panel控制和然後從代碼隱藏開啓或關閉這些面板的標誌。我想我需要另一種方法與ASP.NET MVC達到相同的目標。

什麼是最好的方法?

感謝您提前提出建議!

回答

2

你可以試試這個方法:

[HttpPost] 
    public ActionResult Index(Contact contactData) 
    { 
     if (ModelState.IsValid) 
     { 
      ContactService service = new ContactService(); 
      if (service.Process(contactData)) 
      { 
       TempData["Success"] = "Your success message."; 
       return RedirectToAction("Index"); 
      } 
      else 
      { 
       TempData["Error"] = "Your fail message.";     
      } 
     } 
     return View(contact); 
    } 
+0

您的解決方案似乎比p.campbell的解決方案有優勢(請參閱我對他的回答的評論)。 TempData與ViewBag形成鮮明對比需要多長時間?它似乎在'RedirectToAction'中存在,而ViewBag顯然不是這種情況。 – Slauma 2011-05-08 11:43:04

+0

TempData存在於這些場景中。數據僅適用於一個請求。但是,如果您需要多個後續請求的數據(比如某個嚮導),則可以通過調用Keep()方法來「延長」此數據。查看MSDN上的更多詳細信息:http://goo.gl/rEQ03 – frennky 2011-05-08 12:24:55

+0

這看起來確實很像完美的方式。在此期間,我瞭解到這種模式甚至有一個名稱:「Post/Redirect/Get(PRG)模式」,並且TempData用於支持這種模式。再次感謝! – Slauma 2011-05-09 14:33:50

2

也許使用ViewBag來幫助實現所有這些。當然這是一個動態的,所以你可以添加&檢查任何你想/需要/期望的道具。

[HttpPost] 
public ActionResult Index(ContactData contactData) 
{ 
    if (ModelState.IsValid) 
    { 
     ContactService service = new ContactService(); 
     bool result = service.Process(contactData); 
     ViewBag.ContactSuccess = true; 
    } 
    else 
    { 
     ViewBag.ModelStateErr= "some err"; 
    } 

    return View(contactData)); 
} 

然後在您的視圖:

if (ViewBag.ContactSuccess !=null && ((bool)ViewBag.ContactSuccess)) 
{ 
     //thanks for posting! 
} 
else 
{ 
    if (ViewBag.ModelStateErr !=null) 
    { 
     //show that we have an err 
    } 
    else 
    { 
     //we have no err nor a 'true' contact success yet 
     //write out the form 
    } 
} 
+2

我不喜歡這個解決方案。它可以工作,但是它會在提交後渲染一個來自輸入數據的from。 – frennky 2011-05-08 00:48:44

+0

這會導致視圖標記中存在一個很大的醜陋塊。不理想的優化和維護。 – 2011-05-08 01:00:45

+0

@frennky:爲什麼這會呈現提交後的表單?在帖子發佈之後,你永遠不會到達第二個else標記,你呢? – Slauma 2011-05-08 10:56:35

1

看起來,你可以發出在客戶端Ajax調用,並基於JSON結果,可以呈現在客戶端不同的內容。

1

我建議編碼了三個不同的看法

  • index.cshtml
  • contactSuccess.cshtml
  • contactFail.cshtml

然後在你的控制中LER,你也有類似的代碼之前

public class ContactController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(ContactData contactData) 
    { 
     if (ModelState.IsValid) 
     { 
      ContactService service = new ContactService(); 
      bool result = service.Process(contactData); 

      return View("contactSuccess.cshtml"); 
     } 
     else 
      return View("contactFail.cshtml", contactData); 
    } 

} 

這樣,每個視圖有一個獨立的,你沒有一個大的直列IF塊在您的標記中間。

或者(這是我怎麼會做),你可以有index.cshtml包含三個諧音......

  • _ContactForm.cshtml
  • _ContactSuccess.cshtml
  • _ContactFail 。cshtml

然後您可以將部分視圖加載到索引視圖中,甚至可以使用AJAX動態地將它們交換出去。

+0

「...你可以將部分視圖加載到索引視圖中......」:這聽起來像是一個很好的解決方案,但我不知道該怎麼做。如果我正確理解你,你的代碼片段提供了三種完全不同的視圖,這是不理想的,因爲所有三個視圖都有公共部分的標記,我需要複製它們。是否可以動態注入不同的局部視圖而不使用Ajax? – Slauma 2011-05-08 10:48:07