31

The default ErrorMessage for StringLength validation is a lot longer than I'd like:

The field {Name} must be a string with a maximum length of {StringLength}.

I would like to change it universally to something like:

Maximum length is {StringLength}.

I'd like to avoid redundantly specifying the ErrorMessage for every string I declare:

    [StringLength(20, ErrorMessage="Maximum length is 20")]
    public string OfficePhone { get; set; }
    [StringLength(20, ErrorMessage="Maximum length is 20")]
    public string CellPhone { get; set; }

I'm pretty sure I remember there being a simple way to universally change the ErrorMessage but cannot recall it.

EDIT:

For the sake of clarification, I'm trying to universally change the default ErrorMessage so that I can input:

    [StringLength(20)]
    public string OfficePhone { get; set; }

and have the error message say:

Maximum length is 20.

snumpy
  • 2,808
  • 6
  • 24
  • 39

2 Answers2

66

You can specify the StringLength attribute as follows on numerous properties

[StringLength(20, ErrorMessageResourceName = "StringLengthMessage", ErrorMessageResourceType = typeof(Resource))]
public string OfficePhone { get; set; }
[StringLength(20, ErrorMessageResourceName = "StringLengthMessage", ErrorMessageResourceType = typeof(Resource))]
public string CellPhone { get; set; }

and add the string resource (named StringLengthMessage) in your resource file

"Maximum length is {1}"

Message is defined once and has a variable place holder should you change your mind regarding the length to test against.

You can specify the following:

  1. {0} - Name
  2. {1} - Maximum Length
  3. {2} - Minimum Length

Update

To minimize duplication even further you can subclass StringLengthAttribute:

public class MyStringLengthAttribute : StringLengthAttribute
{
    public MyStringLengthAttribute() : this(20)
    {
    }

    public MyStringLengthAttribute(int maximumLength) : base(maximumLength)
    {
        base.ErrorMessageResourceName = "StringLengthMessage";
        base.ErrorMessageResourceType = typeof (Resource);
    }
}

Or you can override FormatErrorMessage if you want to add additional parameters. Now the properties look as follows:

[MyStringLength]
public string OfficePhone { get; set; }
[MyStringLength]
public string CellPhone { get; set; }
bloudraak
  • 5,902
  • 5
  • 37
  • 52
  • Is there a way to override the default, without having to have `ErrorMessageResourceName = "StringLengthMessage", ErrorMessageResourceType = typeof(Resource))]` for every user-inputted string in my schema? – snumpy Mar 02 '12 at 21:24
  • No. But you can subclass StringLengthAttribute and specify the default values. See the update to my answer. – bloudraak Mar 02 '12 at 21:36
  • can I specify a StrengLength (i.e. `[MyStringLength(30)]`? – snumpy Mar 02 '12 at 21:44
  • Yes, that will use the second constructor: `MyStringLengthAttribute(int maximumLength)` – bloudraak Mar 02 '12 at 22:00
  • The top portion of your code works wonderfully (once I figured out how to make a resource file); however, the StringLengthAttribute override seems to only work on the server. I'm not receiving Client-side validation when using [MyStringLength] or [MyStringLength(30)]. Is there a way to have both server- and client-side validation for this override of StringLength? – snumpy Mar 05 '12 at 15:10
  • 1
    Does this help? http://stackoverflow.com/questions/4747184/perform-client-side-validation-for-custom-attribute/4747466#4747466 – bloudraak Mar 07 '12 at 00:31
  • yes, that's just what I'm looking for. A bit more complicated than I had hoped, but useful nonetheless. Thanks for your help. – snumpy Mar 07 '12 at 13:07
  • @WernerStrydom: Just curious where you found what the string format placeholders are. I don't see it in the MSDN documentation. – myermian Aug 15 '13 at 14:07
  • I stepped into the source code of `StringLengthAttribute`. Look at the FormatErrorMessage method. – bloudraak Aug 15 '13 at 16:57
  • I've used the approach of this answer and it works for the maximumLength, but, what about named parameters? Here If I add the MinimumLength it is always considered 0. – Rafael Merlin Mar 12 '14 at 17:31
  • 1
    Manually set the MinimumLength in the constructor as you see fit. – bloudraak Mar 13 '14 at 01:02
  • Should there not be a dot in the end of the message? – Pétur Ingi Egilsson Apr 16 '17 at 15:27
9

Try

[ StringLength(20, ErrorMessage = "Maximum length is {1}") ]

if I recall correctly that should be it.

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Nick Albrecht
  • 16,607
  • 10
  • 66
  • 101
  • And adding the error message to a resource file means it is only specified once. – bloudraak Mar 02 '12 at 21:11
  • 1
    @WernerStrydom, Please post an answer for how to specify it only once, as that is my question. – snumpy Mar 02 '12 at 21:13
  • Yeah I noticed that after I reread your question later. But it looks like you got the full answer you were looking for now. – Nick Albrecht Mar 12 '12 at 22:33
  • 1
    @Yarx: Where did you find the string format placeholder values? It isn't in the MSDN documentation. – myermian Aug 15 '13 at 14:08
  • 1
    I don't recall but upon looking into the source of the StringLengthAttribute, you can find the placeholder logic there. {0} = Field Name, {1} = Max Length, {2} = Min Length – Nick Albrecht Aug 15 '13 at 16:36