How can I get access to MaxLengthAttribute Class to obtain the LENGTH value of a field during validation?

99 views Asked by At

In the handleSubmit-function of a Blazor CRUD component, I have to provide an error message that is based on the DataAnnotation MaxLength-attribute. I would like to show a "custom" C# error message such as below where "??" is coming from the MaxLength-attribute:

$"The 'Vehicle Number' is limited to {??} characters." 

The DataAnnotation in the CRUD-model is:

[Display(Name = "Vehicle Number")]
[MaxLength(12, ErrorMessage = "'{0}' is limited to {1} characters.")]
public string? TXT_VHCL_NUMBER { get; set; }

I know that the namespace is System.ComponentModel.DataAnnotations should have that value, but I don't know how to get my "Vehicle-Number-field" associated to the specific DataAnnotation MaxLength-attribute.

2

There are 2 answers

0
gunr2171 On BEST ANSWER

Values passed to the constructor of an Attribute must be constants (or literals, which are constants).

There's two really easy ways to have your error message show the right number.

First is to just write the number into the string.

[MaxLength(12, ErrorMessage = "'{0}' is limited to 12 characters.")]

Ok, maybe you want to extract the "12" to a variable. Make it a constant then.

class MyData
{
   public const int TXT_VHCL_NUMBER_MAX_LENGTH = 12;

   [MaxLength(TXT_VHCL_NUMBER_MAX_LENGTH , ErrorMessage = $"'{{0}}' is limited to {TXT_VHCL_NUMBER_MAX_LENGTH} characters.")]
   public string? TXT_VHCL_NUMBER { get; set; }
}

Then anywhere else where you want to get that value do MyClass.TXT_VHCL_NUMBER_MAX_LENGTH.

As I understand your question, using reflection to look up attributes on the property is way overkill. Keep it simple.

2
julealgon On

To leverage the max length value on a custom validation message for the MaxLengthAttribute, you need to use the {1} placeholder. This will then be replaced at runtime by the validator itself with the actual number.

For example:

$"The 'Vehicle Number' is limited to {1} characters." 

Note that you can also use replacement {0} to automatically grab the name of the property being validated, so you could actually replace your custom message with a more general template:

$"The '{0}' is limited to {1} characters." 

Of course, you don't get the space between the words this way, as it will use the name of your property as is without doing any transformations on it.

Here is a simple way to see how these values are passed into the format string:

https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/MaxLengthAttribute.cs,84

    /// <summary>
    /// Applies formatting to a specified error message. (Overrides <see cref = "ValidationAttribute.FormatErrorMessage" />)
    /// </summary>
    /// <param name = "name">The name to include in the formatted string.</param>
    /// <returns>A localized string to describe the maximum acceptable length.</returns>
    public override string FormatErrorMessage(string name) {
        // An error occurred, so we know the value is greater than the maximum if it was specified
        return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, Length);
    }

In particular, notice the position of the name and Length values there, which coincide with indexes 0 and 1 in the format string.