默認在ASP.NET MVC 3強類型的編輯頁面通常公開的實體的所有領域。雖然這通常是可行的,但一些領域存在安全風險。例如簡化雜誌訂閱實體可能看起來像:防止ASP.NET MVC EF
public void Subscription() {
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public DateTime SubscribedThru { get; set; }
}
如果我提供了一個編輯頁面允許用戶更改自己的地址,例如,這是一個安全風險包括:SubscribedThru
字段,因爲一個知識淵博,惡意用戶可以通過僞造日期給自己一個免費的10年訂閱(即使我使用@Html.HiddenFor(model => model.SubscribedThru)
。所以我不在編輯頁面html(通過剃鬚刀)以任何方式包括該字段。
我認爲答案可能是使用類似防止結合的嘗試上SubscribedThru
上的編輯方法中,所述控制器:
[HttpPost]
public ActionResult Edit([Bind(Exclude="SubscribedThru")] Subscription subscription) {
if (ModelState.IsValid) {
db.Entry(subscription).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(subscription);
}
當我到了SaveChanges();
線,它會引發錯誤The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
我相信SubscribedThru日期(正確?)不存在,而空值小於SQL Server可以處理。讓我感到意外的是,當我將Binding排除在外時,它甚至試圖更新該字段。
到目前爲止,我最好的解決辦法似乎是創建一個省略了SubscribedThru日期自定義視圖模型,但似乎很多領域的重複,驗證等;如果可能的話,我想讓這個字段SubscribedThru
不受用戶編輯的影響。
我不能說我完全理解UpdateModel
和TryUpdateModel
方法,並想知道這是否是一個方向?我和他們一起玩,EF會因爲複製對象(相同的鍵)而引發錯誤,這會令人困惑。
另外,我不清楚訂閱數據是否從控制器的public ActionResult Edit(int id)
到最終的[HttpPost] public ActionResult Edit(Subscription subscription)...
方法的初始加載中保留,還是行db.Entry(subscription).State = EntityState.Modified;
試圖設置所有數據(我認爲它只是設置了一個標誌,表示「編輯過的EF-should-save-this」)。
我是一個長期的.NET開發人員,只是跳躍到我的第一個ASP.NET MVC的項目,所以我可能忽視的東西非常明顯。謝謝你的幫助!
+1視圖模型和AutoMapper。 –
使用視圖模型和AutoMapper看起來比的UpdateModel與白名單「更重的」解決方案。 ViewModel + AutoMapper比UpdateModel解決方案有什麼好處? –
您擁有更強的控制力和不依賴於EF的廣義解決方案。 – bluevector