自定义ModelValidatorProvider不会在第一个请求中调用,但适用于所有其他请求

时间:2018-03-21 08:53:15

标签: asp.net-mvc

我想在我的应用程序中提供一个功能,其中我们在Model中设置的错误消息应来自放置在我的项目中的XML文件。为了实现这一点,我创建了一个扩展DataAnnotationsModelValidatorProvider类的类,在该类中,我已经放置了代码来从XML文件中读取错误消息。该课程如下所示:

public class CustomDataAnnotationsModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
    #region Fields
    private readonly ICaching _cacheService;
    #endregion

    #region Ctor
    public CustomDataAnnotationsModelValidatorProvider(ICaching cacheService)
    {
        this._cacheService = cacheService;
    }
    #endregion

    internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
    {
        return new DataAnnotationsModelValidator(metadata, context, attribute);
    }

    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();

        var additionalValues = attributes.OfType<CustomisedAnnotationAttribute>().FirstOrDefault();
        if (additionalValues != null)
        {
            string _modelName = "";
            string _propertyName = "";

            if (metadata.ContainerType != null)
            {
                _modelName = metadata.ContainerType.Name;
                _propertyName = metadata.PropertyName;
            }

            if (metadata.IsRequired)
            {
                var valRequire = attributes.OfType<RequiredAttribute>().FirstOrDefault();
                if (valRequire != null) valRequire.ErrorMessage = CommonFunctions.GetMetadataFromXML("errorMessage", _propertyName, _modelName, "EN", valRequire.ErrorMessage, _cacheService);
            }

            var valCompare = attributes.OfType<System.ComponentModel.DataAnnotations.CompareAttribute>().FirstOrDefault();
            if (valCompare != null) valCompare.ErrorMessage = CommonFunctions.GetMetadataFromXML("compareErrorMessage", _propertyName, _modelName, "EN", valCompare.ErrorMessage, _cacheService);

            var valRegEx = attributes.OfType<System.ComponentModel.DataAnnotations.RegularExpressionAttribute>().FirstOrDefault();
            if (valRegEx != null) valRegEx.ErrorMessage = CommonFunctions.GetMetadataFromXML("regexErrorMessage", _propertyName, _modelName, "EN", valRegEx.ErrorMessage, _cacheService);

            var valRange = attributes.OfType<RangeAttribute>().FirstOrDefault();
            if (valRange != null) valRange.ErrorMessage = CommonFunctions.GetMetadataFromXML("rangeErrorMessage", _propertyName, _modelName, "EN", valRange.ErrorMessage, _cacheService);

            var valCustomVal = attributes.OfType<CustomValidationAttribute>().FirstOrDefault();
            if (valCustomVal != null) valCustomVal.ErrorMessage = CommonFunctions.GetMetadataFromXML("customValErrorMessage", _propertyName, _modelName, "EN", valCustomVal.ErrorMessage, _cacheService);

        }

        return vals;
    }
}

在上面的代码中,CommonFunctions.GetMetadataFromXML函数负责从XML读取相关的错误消息。

创建此类后,我已在Global.asax中通过编写以下两行代码进行了注册:

ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new CustomDataAnnotationsModelValidatorProvider(container.Resolve<ICaching>()));

现在,我面临的问题是,当我第一次运行应用程序时,我在XML文件中提到的错误消息没有显示给用户,而是显示了默认MVC的错误消息,但是,在后续请求中,我正在显示我在XML文件中定义的错误消息。

请问您能告诉我这种行为背后的原因是什么?我做错了吗?

提前致谢

1 个答案:

答案 0 :(得分:2)

不要在GetValidators()方法的开头添加以下行,而是在return语句之前添加

List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();

因此,在完成上面提到的操作后,此函数将如下所示:

protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        var additionalValues = attributes.OfType<CustomisedAnnotationAttribute>().FirstOrDefault();
        if (additionalValues != null)
        {
            string _modelName = "";
            string _propertyName = "";

            if (metadata.ContainerType != null)
            {
                _modelName = metadata.ContainerType.Name;
                _propertyName = metadata.PropertyName;
            }

            if (metadata.IsRequired)
            {
                var valRequire = attributes.OfType<RequiredAttribute>().FirstOrDefault();
                if (valRequire != null) valRequire.ErrorMessage = CommonFunctions.GetMetadataFromXML("errorMessage", _propertyName, _modelName, "EN", valRequire.ErrorMessage, _cacheService);
            }

            var valCompare = attributes.OfType<System.ComponentModel.DataAnnotations.CompareAttribute>().FirstOrDefault();
            if (valCompare != null) valCompare.ErrorMessage = CommonFunctions.GetMetadataFromXML("compareErrorMessage", _propertyName, _modelName, "EN", valCompare.ErrorMessage, _cacheService);


            var valRegEx = attributes.OfType<System.ComponentModel.DataAnnotations.RegularExpressionAttribute>().FirstOrDefault();
            if (valRegEx != null) valRegEx.ErrorMessage = CommonFunctions.GetMetadataFromXML("regexErrorMessage", _propertyName, _modelName, "EN", valRegEx.ErrorMessage, _cacheService);

            var valRange = attributes.OfType<RangeAttribute>().FirstOrDefault();
            if (valRange != null) valRange.ErrorMessage = CommonFunctions.GetMetadataFromXML("rangeErrorMessage", _propertyName, _modelName, "EN", valRange.ErrorMessage, _cacheService);

            var valCustomVal = attributes.OfType<CustomValidationAttribute>().FirstOrDefault();
            if (valCustomVal != null) valCustomVal.ErrorMessage = CommonFunctions.GetMetadataFromXML("customValErrorMessage", _propertyName, _modelName, "EN", valCustomVal.ErrorMessage, _cacheService);

        }

        List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();

        return vals;
    }

这应该有效。如果这不能解决您的问题,请告诉我。