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?

Dave Brock
  • 287
  • 3
  • 5
  • 14
  • 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 http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2 – drneel Feb 17 '16 at 16:38

1 Answers1

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

Community
  • 1
  • 1
patrykgliwinski
  • 316
  • 1
  • 8
  • Perfect, thank you. I'm too used to client validation being taken care of with the non-custom attributes! – Dave Brock Feb 17 '16 at 16:48
  • Another good article - [The complete guide to validation in ASP.NET MVC 3](http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-1) –  Feb 17 '16 at 21:57