Your menu strings are referenced at runtime, while your attribute is compiled before your app runs
I can understand why this is confusing.
Resource files are fundamentally meant to be used for dynamic behavior. And string values can be altered at run time.
But, when we dig into the usage of this particular string, you are using Resources.FormValidation.ResourceManager.GetString(regularExpression)
resource string as part of the compile instruction to create Postcode
. The Razor Framework will use this data to create annotation templates for validation.
[Required(ErrorMessageResourceType = typeof(Resources.FormValidation), ErrorMessageResourceName = "requiredMsg")]
[Localised(typeof(Resources.FormValidation), "postcodeRegEx", "postcodeMsg")]
[Display(Name = "postcode", ResourceType = typeof(Resources.FormLabels))]
public string Postcode { get; set; }
You are using this string the postcodeRegEx string at COMPILE TIME:
In some cases, compiled and pre-compiled code dependent on string literals can behave differently if the string changes. In other cases, like validation attribute behaviors, you do not get to "re-compile" your object's behavior so easily.
Possible Solutions
To achieve this kind of "end-around", you have to go outside the standard
1) implement an extension to validation attribute (ValidationAttribute
), inheriting from RegularExpressionAttribute
which reads the specific RegEx string from your resource file and passes it to the base RegEx Attribute.
// New attribute loads RegEx when needed
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class LocalisedAttribute : RegularExpressionAttribute
{
static LocalizedRegexAttribute()
{
// necessary to enable client side validation
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(LocalizedRegexAttribute), typeof(RegularExpressionAttributeAdapter));
}
public LocalisedAttribute(Type resource, string regularExpressionKey, string errorMessage)
: base(LoadRegex(regularExpressionKey))
{
ErrorMessageResourceType = resource;
ErrorMessageResourceName = errorMessage;
}
private static string LoadRegex(string key)
{
var resourceManager = new ResourceManager(typeof(Resources.FormValidation));
return resourceManager.GetString(key);
}
}
2) use JQuery to make input's data-val-regex-pattern = @ViewBag.RegEx
It will reference the JQuery function
$.validator.unobtrusive.adapters.add('Postcode ', function(options) { /*...*/ });
And I suspect the data-val-regex-pattern
for the Postcode input will be set to the value from your initial resource file.