Asp.net-Mvc

ASP.NET MVC 和 ViewState

  • March 20, 2013

現在我看到了一些這樣的問題,但這並不是我想問的,所以對於那些尖叫的重複,我道歉:)。

我幾乎沒有接觸過 ASP.NET MVC,但據我了解,沒有 ViewState/ControlState … 很好。所以我的問題是保留控制項狀態的替代方法是什麼?我們是否回到老式的 ASP 中,我們可以通過使用控制項的狀態或使用 MVC 創建隱藏的表單輸入來模擬 ASP.NET ViewState/ControlState 所做的事情,我們只是假設 AJAX 始終並保留所有狀態客戶端並製作 AJAX來電更新?

這個問題有一些答案,Maintaining viewstate in Asp.net mvc? ,但不完全是我正在尋找的答案。

更新:感謝到目前為止的所有答案。只是為了清除我不尋找的東西和我正在尋找的東西:

不尋找:

  • 會話解決方案
  • 餅乾解決方案
  • 不想在 MVC 中模仿 WebForms

我在/正在尋找什麼:

  • 一種僅在數據未反彈到控制項時保留回發狀態的方法。將 WebForms 想像為僅在初始頁面載入時綁定網格的場景,即僅在必要時重新綁定數據。正如我所提到的,我並不是想模仿 WebForms,只是想知道 MVC 提供了哪些機制。

該約定已經可用,而無需跳過太多圈子。訣竅是根據您傳遞給視圖的模型連接 TextBox 值。

[AcceptVerbs(HttpVerbs.Get)]   
public ActionResult CreatePost()
{
 return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreatePost(FormCollection formCollection)
{
 try
 {
   // do your logic here

   // maybe u want to stop and return the form
   return View(formCollection);
 }
 catch 
 {
   // this will pass the collection back to the ViewEngine
   return View(formCollection);
 }
}

接下來發生的是 ViewEngine 採用 formCollection 並使用 Html 幫助程序將集合中的鍵與您在視圖中擁有的 ID 名稱/值進行匹配。例如:

<div id="content">

 <% using (Html.BeginForm()) { %>

 Enter the Post Title: <%= Html.TextBox("Title", Model["Title"], 50) %><br />
 Enter the Post Body: <%= Html.TextArea("Body", Model["Body"]) %><br />

 <%= Html.SubmitButton() %>

 <% } %>

</div>

注意 textbox 和 textarea 有 Title 和 Body 的 ID?現在,請注意我是如何從 View 的 Model 對像中設置值的?由於您傳入了 FormCollection(並且您應該使用 FormCollection 將視圖設置為強類型),您現在可以訪問它。或者,沒有強類型,你可以簡單地使用 ViewData[“Title”] (我認為)。

POOF你神奇的 ViewState。這個概念稱為約定優於配置。

現在,上面的程式碼是使用 FormCollection 的最簡單、最原始的形式。當您開始使用 ViewModels 而不是 FormCollection 時,事情會變得有趣。您可以開始添加自己的模型/視圖模型驗證,並讓控制器自動冒泡自定義驗證錯誤。不過,這是另一天的答案。

我會建議使用 PostFormViewModel 而不是 Post 對象,但要每個人自己。無論哪種方式,通過在 action 方法上需要一個對象,您現在可以獲得一個可以呼叫的 IsValid() 方法。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreatePost(Post post)
{

 // errors should already be in the collection here
 if (false == ModelState.IsValid())
   return View(post);

 try
 {
   // do your logic here

   // maybe u want to stop and return the form
   return View(post);
 }
 catch 
 {
   // this will pass the collection back to the ViewEngine
   return View(post);
 }
}

你的強類型視圖需要調整:

<div id="content">

 <% using (Html.BeginForm()) { %>

 Enter the Post Title: <%= Html.TextBox("Title", Model.Title, 50) %><br />
 Enter the Post Body: <%= Html.TextArea("Body", Model.Body) %><br />

 <%= Html.SubmitButton() %>

 <% } %>

</div>

您可以更進一步,並直接從您在控制器中設置的 ModelState 在視圖中顯示錯誤。

<div id="content">

 <%= Html.ValidationSummary() %>

 <% using (Html.BeginForm()) { %>

 Enter the Post Title: 
   <%= Html.TextBox("Title", Model.Title, 50) %>
   <%= Html.ValidationMessage("Title") %><br />

 Enter the Post Body: 
   <%= Html.TextArea("Body", Model.Body) %>
   <%= Html.ValidationMessage("Body") %><br />

 <%= Html.SubmitButton() %>

 <% } %>

</div>

這種方法的有趣之處在於,您會注意到我沒有設置驗證摘要,也沒有設置視圖中的單個驗證消息。我喜歡練習 DDD 概念,這意味著我的驗證消息(和摘要)在我的域中進行控制,並以集合的形式傳遞。然後,我遍歷集合(如果存在任何錯誤)並將它們添加到目前的 ModelState.AddErrors 集合中。當您返回 View(post) 時,其餘部分是自動的。

很多很多的約定都出來了。我強烈推薦的幾本書更詳細地介紹了這些模式:

按照這個順序,第一個涵蓋了整個 MVC 框架的基本細節。後者涵蓋了 Microsoft 官方領域之外的高級技術,以及一些使您的生活更輕鬆的外部工具(Castle Windsor、Moq 等)。

引用自:https://stackoverflow.com/questions/1473483