在Custom RegularExpressionAttribute中,构造函数在第一次调用后没有调用

时间:2012-08-27 15:41:01

标签: c# asp.net-mvc-3 c#-4.0 localization custom-attributes

我们为MVC3应用程序编写了一个自定义RegularExpressionAttribute。自定义RegularExpressionAttribute的目的是,我们希望使用关键字替换资源文件消息中的标记。例如。 “字段__有一些无效字符”。

因此,我们希望将_令牌替换为Address关键字。

ResourceManager(_resourceManagerType.FullName, 
System.Reflection.Assembly.Load(AssemblyNames.TRUETRAC_RESOURCES)).GetString(_errorMessageResourceName).Replace("_","Address");

Custom属性如下,

public class CustomRegularExpressionAttribute : RegularExpressionAttribute
{
    string _errorMessageResourceName;
    Type _resourceManagerType;

    public CustomRegularExpressionAttribute(string _pattern, string fieldName, string errorMessageResourceName, Type resourceManagerType)
        : base(_pattern)
    {
        _errorMessageResourceName = errorMessageResourceName;
        _resourceManagerType = resourceManagerType;

        this.ErrorMessage = FormatErrorMessage(fieldName);
    }
    public override string FormatErrorMessage(string fieldName)
    {
        return //Resources.en_MessageResource.ResourceManager.GetString(fieldName);
        new ResourceManager(_resourceManagerType.FullName, System.Reflection.Assembly.Load(AssemblyNames.TRUETRAC_RESOURCES)).GetString(_errorMessageResourceName).Replace("__", fieldName);    
    }
}

public class CustomRegularExpressionValidator : DataAnnotationsModelValidator<CustomRegularExpressionAttribute>
{
    private readonly string _message;
    private readonly string _pattern;

    public CustomRegularExpressionValidator(ModelMetadata metadata, ControllerContext context, CustomRegularExpressionAttribute attribute)
        : base(metadata, context, attribute)
    {
        _pattern = attribute.Pattern;
        _message = attribute.ErrorMessage;
    }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = _message,
            ValidationType = "regex"
        };

        rule.ValidationParameters.Add("pattern", _pattern);

        return new[] { rule };
    }
}

然后我们在Global.aspx Application_Start事件中注册此属性。

void Application_Start(object sender, EventArgs e)
    {

        AreaRegistration.RegisterAllAreas();

        // Register CustomRegularExpressionValidator
        DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRegularExpressionAttribute), typeof(CustomRegularExpressionValidator));

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

并应用于我们的模型属性:

[CustomRegularExpression(RegularExpression.Alphanumeric, "Address", "CV_Address", typeof(Resources.en_MessageResource))]
    public string Address { get; set; }

问题是我们在我们的应用程序中实现本地化,CustomRegularExpressionAttribute的构造函数只调用一次。 就像启动应用程序的文化是英语然后我们将应用程序的文化更改为西班牙语一样,但CustomRegularExpressionAttribute的消息仍然以英语显示,因为CustomRegularExpressionAttribute的构造函数只调用一次,并且它被要求提供英文信息。

任何人都能说出问题的原因吗?为什么CustomRegularExpressionAttribute的构造函数没有调用每个请求?

2 个答案:

答案 0 :(得分:0)

方法Application_Start仅在应用开始处调用一次。此外,编译属性,因此可以在运行时读取(通过反射或元数据),但不能更改它们。

答案 1 :(得分:0)

我在自定义验证属性的构造函数中初始化ErrorMessage属性时遇到了同样的问题。

我的解决方案是覆盖IsValid方法。只需在此处拨打base.IsValid即可。如果此方法有效,则返回null,否则它将返回ValidationResult,您可以在其中设置ErrorMessage属性。

    public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{    
            public RequiredAttribute()
            {
            }

            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
                    {
                        string displayName = validationContext.DisplayName;
                        ValidationResult result = base.IsValid(value, validationContext);
                        if (result != null)
                            result.ErrorMessage = string.Format(GetTranslatation("RequiredField"), displayName);
                        return result;
                    }
            }
    }

由于IsValid始终在验证期间执行,因此它将始终以当前语言返回消息。