2009-11-19 45 views
2

我目前將我的項目遷移到MVC 2,並且在使用默認模型綁定和驗證時IDataErrorInfo似乎不起作用。它被切斷了嗎?在MVC 2中進行模型驗證時IDataErrorInfo是否被忽略?

+0

啊,這是很好的知道。我剛剛使用xVal進行了驗證,將其與Linq to Sql集成的關鍵部分依賴於IDataErrorInfo來利用好友類。 我希望這個支持在它發佈之前被添加到Mvc 2中... – Dusda 2009-11-19 20:52:55

回答

2

摘要

我張貼這種錯誤MVC 2的問題跟蹤:http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=4891

它將在明年預覽版中得到解決。


DefaultModelBinder在MVC 1.0:

protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) 
{ 
    IDataErrorInfo model = bindingContext.Model as IDataErrorInfo; 
    if (model != null) 
    { 
     string str = model[propertyDescriptor.Name]; 
     if (!string.IsNullOrEmpty(str)) 
     { 
      string key = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name); 
      bindingContext.ModelState.AddModelError(key, str); 
     } 
    } 
} 

DefaultModelBinder在MVC 2.0的β:

protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) 
{ 
    ModelMetadata metadata = bindingContext.PropertyMetadata[propertyDescriptor.Name]; 
    metadata.Model = value; 
    string prefix = CreateSubPropertyName(bindingContext.ModelName, metadata.PropertyName); 
    foreach (ModelValidator validator in metadata.GetValidators(controllerContext)) 
    { 
     foreach (ModelValidationResult result in validator.Validate(bindingContext.Model)) 
     { 
      bindingContext.ModelState.AddModelError(CreateSubPropertyName(prefix, result.MemberName), result.Message); 
     } 
    } 
    if ((bindingContext.ModelState.IsValidField(prefix) && (value == null)) && !TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType)) 
    { 
     bindingContext.ModelState.AddModelError(prefix, GetValueRequiredResource(controllerContext)); 
    } 
} 

它不使用IDataErrorInfo的這個[字符串COLUMNNAME]屬性...好像一個錯誤,因爲DefaultModelBinder仍然使用Error屬性。至少是不一致的。

編輯

我用反射鏡,發現DataErrorInfoPropertyModelValidator似乎並沒有被使用,所以我創建了自己的類:

public class DataErrorInfoModelPropertyValidatorProvider : ModelValidatorProvider 
{ 
    // Methods 
    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) 
    { 
     if (metadata == null) 
     { 
      throw new ArgumentNullException("metadata"); 
     } 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 

     var validators = new List<ModelValidator>(); 
     validators.Add(new DataErrorInfoPropertyModelValidator(metadata, context)); 
     return validators; 
    } 

    internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator 
    { 
     // Methods 
     public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext) 
      : base(metadata, controllerContext) 
     { 
     } 

     public override IEnumerable<ModelValidationResult> Validate(object container) 
     { 
      if (container != null) 
      { 
       IDataErrorInfo info = container as IDataErrorInfo; 
       if (info != null) 
       { 
        string str = info[Metadata.PropertyName]; 
        if (!string.IsNullOrEmpty(str)) 
        { 
         ModelValidationResult[] resultArray = new ModelValidationResult[1]; 
         ModelValidationResult result = new ModelValidationResult(); 
         result.Message = str; 
         resultArray[0] = result; 
         return resultArray; 
        } 
       } 
      } 
      return Enumerable.Empty<ModelValidationResult>(); 
     } 
    } 
} 

然後我用:

ModelValidatorProviders.Providers.Add(new DataErrorInfoModelPropertyValidatorProvider()); 

它工作:)這只是臨時解決方案。將要在最後的MVC 2

編輯

我也改變if (base.Metadata.Model != null)到如果(容器!= NULL)在DataErrorInfoPropertyModelValidatorValidate()方法進行修正。

+0

上面示例中對ModelValidator.Validate()的調用應最終調用到IDataErrorInfo中。你能否詳細解釋「似乎不起作用」? – Levi 2009-11-19 23:03:20

+0

Hi5。很好的工作。應該將這個bug發佈給Scott Gu或其他MVC傢伙的博客 - 然後可以快速修復。 – 2009-11-22 09:37:42

+0

@cottsak:我確實發佈了它來發布跟蹤器。下一個預覽版本應該刪除該問題:http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=4891 – LukLed 2009-11-22 11:58:45

1

這當然是在MVC 2 Preview 2中。看看DefaultModelBinder.OnPropertyValidatingOnModelUpdated

+1

它從OnPropertyValidating中刪除,但不是OnModelUpdated。 OnPropertyValidating是我所需要的。有合適的錯誤,因爲它顯示不一致。 – LukLed 2009-11-19 20:38:32

+0

很可能,我在早期的MVC 1.0預覽中發現了這樣的錯誤。它應該被支持,但也許你是對的。我還使用xVal在MVC 1.0中獲得了我的功能,但會考慮MVC 2.0中的新增功能。很高興知道這可能需要工作。 – 2009-11-22 09:35:50