簡體   English   中英

ASP.NET MVC 2 Beta-默認模型活頁夾

[英]ASP.NET MVC 2 Beta - Default Model Binder

從ASP.NET MVC 1.0切換到ASP.NET MVC 2 Beta后,我遇到一些不同的行為。 我檢查了重大更改,但不清楚問題出在哪里。

該問題與默認模型綁定程序和實現IDataErrorInfo的模型有關。

屬性(IDataErrorInfo.Item):

public string this[string columnName]

不再為每個屬性調用。 我想念什么?

MVC 1.0中的DefaultModelBinder:

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);
        }
    }
}

MVC 2.0 Beta中的DefaultModelBinder:

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的this [string 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中必須進行更正。

編輯

我還將DataErrorInfoPropertyModelValidator Validate()方法中的if (base.Metadata.Model != null)更改為if(container!= null)。

經過進一步的調試工作,我相信我理解為什么在我的特殊情況下未調用IDataErrorInfo.Item 在ASP.NET MVC 2 Beta中使用以下代碼來驗證IDataErrorInfo屬性:

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

    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        if (Metadata.Model != null)
        {
            var castContainer = container as IDataErrorInfo;
            if (castContainer != null)
            {
                string errorMessage = castContainer[Metadata.PropertyName];
                if (!String.IsNullOrEmpty(errorMessage))
                {
                    return new[] { new ModelValidationResult { Message = errorMessage } };
                }
            }
        }
        return Enumerable.Empty<ModelValidationResult>();
    }
}

我的模型包含一個System.Nullable<int>屬性,當模型綁定程序綁定HTML帖子中的空字符串時, Metadata.Model等於null,因此驗證不會運行。

這與ASP.NET MVC 1.0根本不同,在ASP.NET MVC 1.0中,此方案一直將驗證程序激發到對IDataErrorInfo.Item的調用。

我是否只是沒有按預期使用某種東西?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM