2011-07-06 120 views
5

我正在使用ASP.NET MVC 3,並且有幾個頁面,其中大部分視圖模型是隻讀的。一個例子領域會像這樣:ASP.NET MVC 3 - 在視圖中處理模型的最佳實踐

<div class="display-label">My Field</div> 
<div class="display-field">@Model.MyField</div> 

後來我就當用戶在輸入一些驗證文字,像這樣一個領域:當用戶提交表單

@Html.LabelFor(model => model.Verification) 
@Html.PasswordFor(model => model.Verification) 

和它擊中我控制器,除驗證字段外,ViewModel的字段全爲空。我身邊有這樣得到的方式,到目前爲止,是有幾個HiddenFor領域像這樣:

@Html.HiddenFor(model => model.MyField) 

然而,這變得醜陋真快。有沒有更好的方式來處理視圖狀態下的模型,所以在表單提交的POST過程中,我可以獲取所有的字段?如果驗證文本在POST期間不匹配,這很重要,我需要返回視圖模型而不從數據庫重新檢索它。

感謝您的任何建議。

回答

3

沒有更好的解決方法,無需從數據庫中重新檢索值。原因是因爲MVC的模型綁定僅查看GET或POST參數以將MyField綁定到動作的模型,並且如果GET/POST參數沒有MyField值,那麼它必須將該屬性保留爲空(否則它是否會知道值應該是什麼?)

爲了讓模型聯編程序看到您的MyField的值是在GET/POST參數中傳遞它,要做到這一點,你必須明確地告訴你的視圖的表單通過Html.HiddenFor()傳遞值。視圖無法自動知道在post/get參數中發送該屬性。

然而一個想法,你可以看看是創建一個剃刀(或HTML)helper方法接受一個字段名和表達式(x => x.MyField),並寫入以下爲你輸出:

<div class="display-label">My Field</div> 
<div class="display-field">@Model.MyField</div> 
@Html.HiddenFor(model => model.MyField) 

這意味着你只需要編寫一行代碼(類似於@Html.ShowReadOnlyField(x => x.MyField, "My Field"),而不是那些三線但是,這也假定無處不在,你想這樣做,將有相同的div結構

編輯:物權法請記住只讀字段的安全性問題,因爲它們不是真正的只讀字段。如果此數據將用於控制器中的任何內容,則最好從數據庫中重新檢索此數據,因爲即使只讀取了HTML表單,用戶仍然可以通過操作POST/GET數據將此值設置爲任何他們想要的值。

+0

你可以通過使用助手'@ Html.AntiForgeryToken()'來解決安全問題嗎? – Brandon

+1

我對此表示懷疑。我不太瞭解AntiForgeryToken功能,但很可能用戶可以查看頁面的源代碼,以查看它們需要提供哪些令牌才能運行。僞造令牌更多用於跨站點腳本攻擊,而不是用於價值保護,現在有辦法知道是否要提供字段。任何意味着安全的事情都需要在服務器端進行處理,並且您不能依賴客戶端功能來實現安全 – KallDrexx

+0

我最終只是將控件中的對象實例重新加載。 – Brandon

0

請嘗試序列化頁面中的模型,然後做一個帖子?這應該解決問題。

<%= Html.Serialize("User",Model) %> 

[HttpPost] 
public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm) 
{ 

} 
+0

Hello ViewState! –