我相信答案指的是過問題。當您直接在視圖中使用實體類時,特別是如果將該發佈的實體直接保存到數據庫中時,惡意用戶可以修改該表單以發佈他們不應該修改的字段。
例如,假設您的表單允許用戶編輯小部件。我們還要說,你有行級權限,這樣用戶只能編輯屬於他們的小部件。所以,我們的虛構的惡意用戶Joe編輯了一個他可以使用id 123編輯的小部件。但是,他決定他想要與Jane的小部件混在一起,所以他在名爲Id
的表單中添加了一個字段,併爲其賦予了Jane的小部件ID。當喬然後發佈窗體小部件時,Jane的窗口小部件將被更新。
視圖模型並不僅僅是爲了解決這個問題,但它基本上否定了這個問題,因爲從本質上講,您不能直接將視圖模型保存到數據庫中。相反,在將實體保存到數據庫之前,必須將視圖模型的值映射到實體上。因此,你明確地控制了什麼和沒有被映射,所以在上面的例子中,Joe改變id最終沒有效果,因爲你沒有將它映射到實體上。
實際上,real這裏的問題是直接將用戶發佈的任何內容直接保存到數據庫中。您實際上仍然可以將實體類作爲「模型」提供給視圖,但不保存發佈的實例。相反,您可以創建實體的新實例或從數據庫中提取新實例,並簡單地將已發佈實例的值映射到該實例。再一次,你不會映射像Id
這樣的屬性,所以Joe又被挫敗了。換句話說,解決問題的不是視圖模型,而是永遠不會相信用戶足以直接保存通過POST創建的任何內容,從而解決問題。
Microsoft以Bind
屬性的形式給出了另一種替代解決方案,它基本上允許您在模型綁定過程中包含/排除實體類的某些屬性(換句話說,忽略任何發佈的值)。因此,例如,您可以通過在[Bind(Exclude = "Id")]
上對您的操作參數進行裝飾來解決上述問題,然後丟棄Id
的任何已發佈值。但是,Bind
對於number of reasons來說太可怕了,您不應該真正使用它。始終使用視圖模型,或者直接不要直接保存由模型綁定器創建的實體實例。
當您使用視圖模型,你推到DB如果您使用的仍然是連接到活動databasecontext的觀點能夠在某些情況下,仍然可以通過壞數據進入DB這不會是一個模型,然後才能驗證數據可以用真實視圖模型。 –
@Derek問題不在於不恰當地管理連接而不是使用ViewModel,然後呢? – Sinjai
問題是模型聯編程序會盲目地更新模型中的值。如果模型連接到實體框架中的某個實體,它最終可能會更新您不想要的字段。一個適當的視圖模型將完全脫離這樣的事情。 –