為什麼 ASP.NET MVC 在數據綁定期間關心我的只讀屬性?
編輯:添加賞金,因為我正在尋找除此之外的 MVC3 解決方案(如果存在):
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
我的“地址”模型上有一個只讀屬性
'CityStateZip'。這只是從美國地址獲取城市、州、郵編的便捷方式。如果國家不是美國,它會拋出異常(呼叫者應該首先檢查)。
public string CityStateZip { get { if (IsUSA == false) { throw new ApplicationException("CityStateZip not valid for international addresses!"); } return (City + ", " + StateCd + " " + ZipOrPostal).Trim().Trim(new char[] {','}); } }這是我模型的一部分,所以它被綁定了。在 ASP.NET MVC2 RC2 之前,此欄位在數據綁定期間從未引起問題。我什至從未真正想過它——畢竟它只是只讀的。
現在雖然在 2010 年 1 月的 RC2 版本中,它在數據綁定期間給了我一個錯誤 - 因為預設模型綁定器似乎想要檢查這個值(即使它是只讀的)。
觸發此錯誤的是“base.OnModelUpdated”行。
public class AddressModelBinder : DefaultModelBinder { protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) { base.OnModelUpdated(controllerContext, bindingContext);模型綁定器的最後幾分鐘更改顯然導致了這種行為變化 - 但我不太確定它的後果是什麼 - 或者這是否是一個錯誤?我正在將此傳遞給 MVC 團隊,但好奇是否有人在此期間有任何建議如何防止此屬性綁定。
這篇文章非常值得一讀有關這些更改的內容——但根本沒有提到只讀屬性(不是我期望的那樣)。問題(如果有的話)可能比這種情況更廣泛 - 我只是不確定是否有任何反擊 - 如果有的話!
根據@haacked 的要求,這是堆棧跟踪:
我只需將以下行添加到 ANY 模型並發佈到相應的操作方法即可。在這種情況下,我將它添加到我最簡單的模型中。
public string Foo { get { throw new Exception("bar"); } }[TargetInvocationException:對象“Rolling_Razor_MVC.Models.ContactUsModel”上的屬性訪問器“Foo”引發以下異常:“bar”] System.ComponentModel.ReflectPropertyDescriptor.GetValue(對象組件)+390 System.Web.Mvc.<c__DisplayClassb.<GetPropertyValueAccessor>b__a() +18 System.Web.Mvc.ModelMetadata.get_Model() +22 System.Web.Mvc. ModelMetadata.get_RealModelType() +29 System.Web.Mvc.<GetValidatorsImpl>d__0.MoveNext() +38 System.Linq.<SelectManyIterator>d__14`2.MoveNext() +273 System.Web.Mvc.<Validate>d__5。 MoveNext() +644 System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +92 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, 對像模型) +60 System.Web.Mvc。 DefaultModelBinder.BindComplexModel(ControllerContext controllerContext,ModelBindingContext bindingContext) +1048 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +280 System.Web.Mvc.Controller.TryUpdateModel(TModel model, String prefix, String[] includeProperties, String[] excludeProperties, IValueProvider valueProvider) +449 System.Web.Mvc.Controller.TryUpdateModel(TModel 模型) +73
我相信我遇到了類似的問題。我已經發布了詳細資訊:
<http://forums.asp.net/t/1523362.aspx>
編輯:MVC 團隊的回應(來自上面的 URL):
我們對此進行了調查並得出結論,驗證系統的行為符合預期。由於模型驗證涉及嘗試對所有屬性執行驗證,並且由於不可為空的值類型屬性具有隱式 [Required] 屬性,因此我們正在驗證此屬性並在此過程中呼叫它的 getter。我們理解這是對產品 V1 的重大更改,但有必要使新的模型驗證系統正常執行。
您有幾個選項可以解決此問題。這些中的任何一個都應該起作用:
- 將 Date 屬性改為方法而不是屬性;這樣它將被 MVC 框架忽略。
- 將屬性類型更改為 DateTime?而不是日期時間。這會從此屬性中刪除隱含的 [Required]。
- 清除靜態 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes 標誌。這從應用程序範圍內的所有不可空值類型屬性中刪除了隱含的 [Required]。我們正在考慮在產品的 V3 中添加一個屬性,該屬性將向我們發出“不要綁定它,不要驗證它,只是假裝這個屬性不存在”的信號。
再次感謝您的報告!