ASP.NET MVC 和 ViewState
現在我看到了一些這樣的問題,但這並不是我想問的,所以對於那些尖叫的重複,我道歉:)。
我幾乎沒有接觸過 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 等)。