0

I have a property with StringLength attribute, but I can assign a string of any length to this property. I created the following test program in VB.NET 4.7 Framework:

Imports System.ComponentModel.DataAnnotations

Module Module1

    Class C1
        <StringLength(3)>
        Public Property BufferId As String
    End Class
    Sub Main()
        Dim c1 = New C1
        c1.BufferId = "abcd"
        Console.WriteLine($"c1.BufferId={c1.BufferId}")
        Console.ReadKey()
    End Sub

End Module

Although StringLength=3, I am able to assign a string of length 4.

How can I make the StringLength attribute to throw an exception, when I assign a string of length longer than the specified length?

1
  • That's not how data annotations are intended to work. They're intended to be used for validating data as it's deserialized into the class, not affect the fundamental operations of properties or fields during normal usage. Commented Mar 8, 2024 at 8:51

2 Answers 2

1

Attributes are (with a few exceptions for compiler-interpreted attributes) passive annotations; they don't do anything unless some code (usually a library such as an ORM or UI toolkit, or a Roslyn analyzer) looks for them, and makes some decisions based on their existence.

If you want to validate things: a property setter can help. I can't remember much VB, but in C# terms:

private string foo;
public string Foo
{
    get => foo;
    set
    {
        ArgumentNullException.ThrowIfNull(value);
        if (value.Length > 4) throw new ArgumentOutOfRangeException(nameof(Foo));
        foo = value;
    }
}

You can of course write your own utility methods to simplify this, allowing things like

private string foo;
public string Foo
{
    get => foo;
    set => foo = value.AssertLengthAtMost(4);
}
...
internal static class ValidationExtensions
{
    public static string AssertLengthAtMost(this string value, int maxLength,
        [CallerArgumentExpression("value")] string? paramName = null)
    {
        ArgumentNullException.ThrowIfNull(value);
        if (value.Length > maxLength)
        {
            throw new ArgumentOutOfRangeException(paramName ?? nameof(value),
                "Max length exceeded");
        }
        return value;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Could I somehow load the instance into Entity Framework? Will then the StringLength attribute forbid assigning strings longer than 3?
@Alex it probably won't stop it being assigned - I imagine EF will validate later, before trying to commit changes
0

It is possible to validate the object with:

Validator.ValidateObject(c1, New ValidationContext(c1), True)

Therefore, the program

Imports System.ComponentModel.DataAnnotations

Module Module1

    Class C1
        <StringLength(3)>
        Public Property BufferId As String
    End Class
    Sub Main()
        Try
            Dim c1 = New C1
            c1.BufferId = "abcd"
            Console.WriteLine($"c1.BufferId={c1.BufferId}")
            Validator.ValidateObject(c1, New ValidationContext(c1), True)
        Catch ex As Exception
            Console.WriteLine(ex)
        End Try
        Console.ReadKey()
    End Sub

End Module

produces the following output:

c1.BufferId=abcd
System.ComponentModel.DataAnnotations.ValidationException: The field BufferId must be a string with a maximum length of 3.
   at System.ComponentModel.DataAnnotations.Validator.ValidationError.ThrowValidationException()
   at System.ComponentModel.DataAnnotations.Validator.ValidateObject(Object instance, ValidationContext validationContext, Boolean validateAllProperties)
   at ConsoleApp1.Module1.Main() in c:\temp\ConsoleApp1\ConsoleApp1\Module1.vb:line 14

Comments

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.