1

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.

7
  • Is the error message made in the Max Length attribute or somewhere else? Commented Feb 7, 2024 at 17:36
  • Do you define the vehicle number field in your code or is it automatically generated from the database model by an ORM library? Commented Feb 7, 2024 at 17:41
  • I added the DataAnnotation-MaxLength to the question-text above. The CRUD-Model has the DataAnnotation MaxLength hand crafted by my coding -- NOT from EF or ORM library. Commented Feb 7, 2024 at 18:00
  • "12" is a number that must be specified at compile time. Why not just type "12" in the ErrorMessage string, or use a constant? Commented Feb 7, 2024 at 18:05
  • Because, since I hand-craft the data-model(s), I would rather have the DataAnnotation-"condition" in one place. Also...I want to improve my C# knowledge to access some of the sophisticated classes that work with Blazor. If you want or need to know "why" I need this "length" is that I have a custom validation that involves other considerations with another field that...in my exerience... DataAnnotation attributes are not suitable for other field-dependencies. Thanks. Commented Feb 7, 2024 at 18:12

2 Answers 2

1

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.

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

Comments

0

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.

2 Comments

Thank you for your reply. I see that in the DEFINITION of the MaxLength attribute. But I do not have the C# experience to reference the namespace and associate my field with the MaxLength attribute in a C# method -- can you help with this?
@JohnD to me it seems like you are asking the wrong question. You said you want "to use the value that is in the attribute", but why don't you just use the entire validation message it produces? You can fire a manual validation against your model that is annotated with the attribute and grab the validation messages from it using the static Validator class. But again, one would question why you are having to do this by yourself considering all frameworks can natively validate models.

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.