0

I am writing a custom attribute to validate that a first and last name does not exceed a certain amount of characters, but the error message is not displaying like it does for out-of-the-box annotations.

Here is my implementation.

public class User
{
    [Required(ErrorMessage = "Last Name is required.")]
    [RegularExpression(@"^[a-zA-Z'\s]{1,50}$", ErrorMessage = "Please enter a valid last name.")]
    [FullNameMaxLength("FirstName")]
    public string LastName { get; set; }
}


public class FullNameMaxLengthAttribute : ValidationAttribute
{
    private string _firstName;

    public FullNameMaxLengthAttribute(string firstName)
    {
        _firstName = firstName;
    }
    protected override ValidationResult IsValid(object lastName, ValidationContext validationContext)
    {
        clsUserRegistration userRegistrationContext = (clsUserRegistration)validationContext.ObjectInstance;

        if (lastName != null)
        {
            string strValue = lastName.ToString();
            PropertyInfo propInfo = validationContext.ObjectType.GetProperty(_firstName);

            if (propInfo == null)
                return new ValidationResult(String.Format("Property {0} is undefined.", _firstName));

            var fieldValue = propInfo.GetValue(validationContext.ObjectInstance, null).ToString();

            if (strValue.Length + fieldValue.Length > 53)
            {
                return new ValidationResult("First and last names are too long!");
            }

            return ValidationResult.Success;
        }

        return null;
    }
}

In my view, I have a ValidationMessageFor, and it works fine with non-custom attributes. When I step through my model, it returns the ValidationMessage, but I cannot see that error message. Any thoughts?

1
  • 1
    I'm assuming that your problem is that it's not validating prior to a submit or post, but the error message is showing up once it goes to the server and comes back. The reason for this is because you have to add javascript to handle the client side processing prior to submit. Here's an article that should get you on the right track devtrends.co.uk/blog/… Commented Feb 17, 2016 at 16:38

1 Answer 1

2

The above is just the "back-end" validation. This for example does still work when user's browser has JavaScript turned off - the page will post back regardless of errors but then show the form again with validation messages on it.

For "front-end" validation, you need something along these lines:

public class FullNameMaxLengthAttribute : ValidationAttribute, IClientValidatable
{
    // Your Properties and IsValid method here

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
            ValidationType = "fullnamemaxlength"
        };

        rule.ValidationParameters["firstname"] = FirstName;
        rule.ValidationParameters["maxlength"] = 53;

        yield return rule;
    }
}

And then in JavaScript that is added to the page:

if (jQuery.validator) {
    jQuery.validator.addMethod("fullnamemaxlength", function(value, element, param) {
    var name = param.firstname;
    var max = param.maxlength;
    return name.length > max;
});

jQuery.validator.unobtrusive.adapters.add("fullnamemaxlength", ["firstname", "maxlength"], function (options) {
        options.rules.fullnamemaxlength = {};
        options.rules.fullnamemaxlength.firstname = options.params.firstname;
        options.rules.fullnamemaxlength.maxlength = options.params.maximum;
        options.messages.fullnamemaxlength = options.message;
    }
);
}

Note this sits OUTSIDE of document.ready() { };

Something similar here: client-side validation in custom validation attribute - asp.net mvc 4

Sign up to request clarification or add additional context in comments.

2 Comments

Perfect, thank you. I'm too used to client validation being taken care of with the non-custom attributes!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.