2011-03-11 63 views

回答

44

您可以使用此方法通過給定的控制器更新支持特定視圖的模型。例如,如果我有一個視圖顯示帶有由文本框填充的屬性Bar的Foo對象,則可以在控制器上調用Save()方法,並調用TryUpdateModel嘗試更新Foo。

public class Foo { 
    public string Bar { get; set; } 
} 

// ... in the controller 
public ActionResult Save() { 
    var myFoo = new Foo(); 
    TryUpdateModel(myFoo); 
} 

這將嘗試使用Bar的給定值更新模型。如果更新驗證失敗(比如說,Bar是一個整數,並且文本框中有文本「hello」),則TryUpdateModel將傳遞更新ViewData ModelState的驗證錯誤,並且您的視圖將顯示驗證錯誤。

請務必密切注意安全警告爲MSDN文檔中的.NET Framework 4:

安全注意使用 [超載之一:System.Web.Mvc.Controller。 TryUpdateModel``1] 方法,其中包含 屬性列表以包含(白名單)或 要排除的屬性列表( 黑名單)。如果沒有明確的白名單 或黑名單通過, [過載:System.Web.Mvc.Controller.TryUpdateModel`1] 方法嘗試更新模型中的每個公共 屬性對此有 在 的對應值請求。惡意用戶 可以利用此功能來更新 屬性,您不打算通過 提供訪問權限。

https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel(v=vs.100).aspx

+11

+1包含關於質量分配的安全警告。這個漏洞對大多數MVC框架來說都很常見,並且是GitHub被運用的原因(http://www.extremetech.com/computing/120981-github-hacked-millions-of-projects-at-risk-of-being-改性或缺失)。 – 2012-05-22 07:21:28

+1

當您不使用TryUpdateModel時,該漏洞也適用。你也可以指定一個白名單:public ActionResult ActionName([Bind(Exclude =「FieldName」] Model) or blacklist public ActionResult ActionName([Bind(Exclude =「FieldName」] Model) 當你不依賴於TryUpdateModel 。 http://odetocode.com/blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx – Rui 2013-10-03 14:28:37

16

TryUpdateModel()允許您將參數綁定到你的行動裏你的模型。如果要從數據庫加載模型,然後根據用戶輸入更新模型,而不是從用戶輸入中獲取整個模型,這非常有用。

public ActionResult Update(int id) { 
    var service = new ServiceClass(); 
    var record = service.LoadModel(id); 
    if (!TryUpdateModel(record)) { 
     // There was an error binding data 
     return View(); 
    } 
    // Everything was ok, now save the record back to the database 
    service.SaveModel(record); 
    return View("Success"); 
} 

它的作用類似於在這方面UpdateModel(),但如果有一個錯誤在成功時返回true和false。如果出現需要多一點代碼的錯誤,則UpdateModel()會引發異常。

注意:您可能希望使用其中一種重載,允許您限制哪些屬性可以更新。

12

我們還使用TryUpdateModel來避免在動作被調用之前的模型綁定魔法;相反,我們採取了HttpFormCollection作爲我們的參數,並在該方法內調用TryUpdateModel。從此允許的控制流返回的乾淨布爾值將傳遞給Action的成功或失敗方法。例如

public ActionResult Save(HttpFormCollection formCollection) 
{ 
    var saveModel = new SaveModel(); // or from a Factory etc 
    var validModel = TryUpdateModel(_saveModel, formCollection); // order may be incorrect 
    return validModel ? Save(saveModel) : InvalidSaveModel(saveModel); 
} 

我們覺得這是很容易建立一個HttpFormCollection爲我們的所有驗證的情況下,因此測試的動作。

相關問題