ASP.NET MVC - "Validation type names must be unique."
I use ASP.NET MVC 3 and Data Annotations in my model, and want to retrieve the Error Messages from a database. So I wrote inherited attributes:
public class LocalizedRequiredAttribute : RequiredAttribute
{
public LocalizedRequiredAttribute(){}
public override string Forma开发者_StackOverflow社区tErrorMessage(string name)
{
return GetByKeyHelper.GetByKey(this.ErrorMessage);
}
}
public class LocalizedRegularExpressionAttribute : RegularExpressionAttribute
{
public LocalizedRegularExpressionAttribute(string pattern) : base(pattern){}
public override string FormatErrorMessage(string name)
{
return GetByKeyHelper.GetByKey(this.ErrorMessage);
}
}
I wrote 2 "adapters" for these attributes to enable client validations, such as this:
public class LocalizedRequiredAttributeAdapter : DataAnnotationsModelValidator<LocalizedRequiredAttribute>
{
public LocalizedRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, LocalizedRequiredAttribute attribute)
: base(metadata, context, attribute)
{
}
public static void SelfRegister()
{
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(LocalizedRequiredAttribute), typeof(RequiredAttributeAdapter));
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return new[] { new ModelClientValidationRequiredRule(ErrorMessage) };
}
}
And in my global.asax I have these 2 lines:
LocalizedRegularExpressionAttributeAdapter.SelfRegister();
LocalizedRequiredAttributeAdapter.SelfRegister();
I get an exception "Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: required" when my model renders the HTML for this property:
[LocalizedRequired(ErrorMessage = "global_Required_AccountName")]
[LocalizedRegularExpression(User.ADAccountMask, ErrorMessage = "global_Regex_AccountName")]
public string AccountName { get; set; }
What is wrong?
I basically had the same problem and I managed to solve it with the following piece of code:
using System;
using System.Web.Mvc;
And the ValidationRule:
public class RequiredIfValidationRule : ModelClientValidationRule
{
private const string Chars = "abcdefghijklmnopqrstuvwxyz";
public RequiredIfValidationRule(string errorMessage, string reqVal,
string otherProperties, string otherValues, int count)
{
var c = "";
if (count > 0)
{
var p = 0;
while (count / Math.Pow(Chars.Length, p) > Chars.Length)
p++;
while (p > 0)
{
var i = (int)(count / Math.Pow(Chars.Length, p));
c += Chars[Math.Max(i, 1) - 1];
count = count - (int)(i * Math.Pow(Chars.Length, p));
p--;
}
var ip = Math.Max(Math.Min((count) % Chars.Length, Chars.Length - 1), 0);
c += Chars[ip];
}
ErrorMessage = errorMessage;
// The following line is where i used the unique part of the name
// that was generated above.
ValidationType = "requiredif"+c;
ValidationParameters.Add("reqval", reqVal);
ValidationParameters.Add("others", otherProperties);
ValidationParameters.Add("values", otherValues);
}
}
I hope this helps.
I'm guessing that maybe the line that reads:
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedRequiredAttribute),
typeof(RequiredAttributeAdapter));
Should read:
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(LocalizedRequiredAttribute),
typeof(LocalizedRequiredAttributeAdapter));
That's the correct answer in a similar question: https://stackoverflow.com/a/5418124/80434
Basically, you can't have both attributes at the same time
精彩评论