/
StringLengthAttribute.cs
97 lines (85 loc) · 4.09 KB
/
StringLengthAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
namespace System.ComponentModel.DataAnnotations
{
/// <summary>
/// Validation attribute to assert a string property, field or parameter does not exceed a maximum length
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false)]
public class StringLengthAttribute : ValidationAttribute
{
/// <summary>
/// Constructor that accepts the maximum length of the string.
/// </summary>
/// <param name="maximumLength">The maximum length, inclusive. It may not be negative.</param>
public StringLengthAttribute(int maximumLength)
: base(() => SR.StringLengthAttribute_ValidationError)
{
MaximumLength = maximumLength;
}
/// <summary>
/// Gets the maximum acceptable length of the string
/// </summary>
public int MaximumLength { get; }
/// <summary>
/// Gets or sets the minimum acceptable length of the string
/// </summary>
public int MinimumLength { get; set; }
/// <summary>
/// Override of <see cref="ValidationAttribute.IsValid(object)" />
/// </summary>
/// <remarks>
/// This method returns <c>true</c> if the <paramref name="value" /> is null.
/// It is assumed the <see cref="RequiredAttribute" /> is used if the value may not be null.
/// </remarks>
/// <param name="value">The value to test.</param>
/// <returns><c>true</c> if the value is null or less than or equal to the set maximum length</returns>
/// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
public override bool IsValid(object? value)
{
// Check the lengths for legality
EnsureLegalLengths();
// Automatically pass if value is null. RequiredAttribute should be used to assert a value is not null.
// We expect a cast exception if a non-string was passed in.
if (value == null)
{
return true;
}
int length = ((string)value).Length;
return length >= MinimumLength && length <= MaximumLength;
}
/// <summary>
/// Override of <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>
/// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
public override string FormatErrorMessage(string name)
{
EnsureLegalLengths();
bool useErrorMessageWithMinimum = MinimumLength != 0 && !CustomErrorMessageSet;
string errorMessage = useErrorMessageWithMinimum
? SR.StringLengthAttribute_ValidationErrorIncludingMinimum
: ErrorMessageString;
// it's ok to pass in the minLength even for the error message without a {2} param since string.Format will just
// ignore extra arguments
return string.Format(CultureInfo.CurrentCulture, errorMessage, name, MaximumLength, MinimumLength);
}
/// <summary>
/// Checks that MinimumLength and MaximumLength have legal values. Throws InvalidOperationException if not.
/// </summary>
private void EnsureLegalLengths()
{
if (MaximumLength < 0)
{
throw new InvalidOperationException(SR.StringLengthAttribute_InvalidMaxLength);
}
if (MaximumLength < MinimumLength)
{
throw new InvalidOperationException(SR.Format(SR.RangeAttribute_MinGreaterThanMax, MaximumLength, MinimumLength));
}
}
}
}