Reputation: 639
The default StringLength validation error message is too long for my purposes, so I would like to make it shorter.
I know I can specify the ErrorMessage for each property, but I rather not duplicate this all over the place:
[StringLength(25, ErrorMessage = "Max length is {1}")]
[DisplayName("Address")]
public virtual string BillAddress1 { get; set; }
Based on this post, Modify default ErrorMessage for StringLength validation, I subclassed StringLengthAttribute:
public class CustomStringLengthAttribute : StringLengthAttribute
{
public CustomStringLengthAttribute()
: this(20)
{
}
public CustomStringLengthAttribute(int maximumLength)
: base(maximumLength)
{
base.ErrorMessage = "Max length is {1}";
}
}
And changed to use CustomStringLengthAttribute instead:
[CustomStringLength(25)]
[DisplayName("Address")]
public virtual string BillAddress1 { get; set; }
This compiles fine, and I set a breakpoint in the CustomStringLengthAttribute constructor to verify that it gets hit, but unobtrusive validation no longer works - invalid data gets posted back to the controller.
It works fine when I do not use my subclassed version.
Also, here is the javascript validation:
if (validation.validateForm($('#addressForm'))) {
....
}
validateForm:
function validateForm(form) {
prepareValidationScripts(form);
var validator = $.data(form[0], 'validator');
return validator.form();
}
function prepareValidationScripts(form) {
if (form.executed)
return;
form.removeData("validator");
$.validator.unobtrusive.parse(document);
form.executed = true;
}
What am I missing?
Thanks.
Upvotes: 0
Views: 1974
Reputation: 2355
Try this having custom validation.
CustomStringLengthAttribute.cs
public class CustomStringLengthAttribute : ValidationAttribute, IClientValidatable
{
public int MaximumLength
{
get;
private set;
}
public int MinimumLength
{
get;
set;
}
public CustomStringLengthAttribute(int maximumLength)
: base(new Func<string>(CustomStringLengthAttribute.GetDefaultErrorMessage))
{
this.MaximumLength = maximumLength;
}
private static string GetDefaultErrorMessage()
{
return "Max length {1}";
}
public override string FormatErrorMessage(string name)
{
return string.Format(base.ErrorMessageString, name, this.MaximumLength, this.MinimumLength);
}
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
string text = (string)value;
int maximumLength = this.MaximumLength;
int minimumLength = this.MinimumLength;
if (maximumLength < 0)
{
throw new InvalidOperationException("The maximum length must be a nonnegative integer.");
}
if (minimumLength > maximumLength)
{
throw new InvalidOperationException(string.Format("The maximum value '{0}' must be greater than or equal to the minimum value '{1}'.", maximumLength, minimumLength));
}
int length = text.Length;
return length <= maximumLength && length >= minimumLength;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationParameters.Add("max", MaximumLength);
rule.ValidationParameters.Add("min", MinimumLength);
rule.ValidationType = "customstringlength";
yield return rule;
}
}
In js file:
/// <reference path="jquery-1.4.4.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
if ($.validator && $.validator.unobtrusive) {
$.validator.unobtrusive.adapters.addMinMax("customstringlength", "min","max");
$.validator.addMethod("customstringlength", function (value, element, min,max) {
if (value) {
if (value.length<min || value.length>max) {
return false;
}
}
return true;
});
}
Model class:
[CustomStringLength(25)]
[DisplayName("Address")]
public virtual string BillAddress1 { get; set; }
Upvotes: 1