IDataErrorInfo игнорируется во время проверки модели в MVC 2? - PullRequest
2 голосов
/ 19 ноября 2009

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

Ответы [ 2 ]

2 голосов
/ 19 ноября 2009

РЕЗЮМЕ

Я опубликовал эту ошибку на трекере 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 это свойство [string 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) на if (container! = Null) в Validate() методе DataErrorInfoPropertyModelValidator.

1 голос
/ 19 ноября 2009

Это определенно в MVC 2 Preview 2. Посмотрите на DefaultModelBinder.OnPropertyValidating и OnModelUpdated.

...