2009-11-19 10 views
2

В настоящее время я переносил свой проект на MVC 2, и IDataErrorInfo, похоже, не работает при использовании привязки и проверки подлинности по умолчанию. Вырезано?Is IDataErrorInfo игнорируется во время проверки модели в MVC 2?

+0

Ах, это полезно знать. Я только что реализовал проверку с помощью xVal, а ключевая часть интеграции с Linq в Sql основана на IDataErrorInfo, чтобы использовать классы друзей. Я надеюсь, что эта поддержка добавляется в Mvc 2 до ее выпуска ... – Dusda

ответ

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. По крайней мере, это несогласованность.

EDIT

Я использовал отражатель и заметил, что 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.

EDIT

Я также изменил if (base.Metadata.Model != null) И.Ф. (контейнер! = NULL) в Validate()DataErrorInfoPropertyModelValidator методом.

+0

Вызов ModelValidator.Validate() в вашем примере выше должен в конечном итоге вызвать в IDataErrorInfo. Не могли бы вы объяснить, что «не работает» более подробно? – Levi

+0

Hi5. Хорошая работа. Должен опубликовать эту ошибку для Скотта Гу или одного из других бэби-репортеров MVC - попробуйте быстро исправить ситуацию. –

+0

@cottsak: Я опубликовал его для выпуска трекера. Следующий предварительный выпуск должен удалить проблему: http://aspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=4891 – LukLed

1

Это, безусловно, в MVC 2 Preview 2. Посмотрите на DefaultModelBinder.OnPropertyValidating и OnModelUpdated.

+1

Удаляется из OnPropertyValidating, но не OnModelUpdated. OnPropertyValidating - это то, что мне нужно. Есть возможная ошибка, потому что она показывает несогласованность. – LukLed

+0

Скорее всего, я нашел ошибки, подобные этому в ранних версиях MVC 1.0. Он должен поддерживаться, но, возможно, вы правы. Я также использовал xVal, чтобы получить свою функциональность в MVC 1.0, но посмотрю на дополнения в MVC 2.0. Приятно знать, что это может потребовать работы. –