-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new System.ComponentModel.DataAnnotations features (#82311)
* Add RangeAttribute.Minimum/MaximumIsExclusive properties. * Add RequiredAttribute.DisallowAllDefaultValues. * Add LengthAttribute implementation & tests. * Add AllowedValuesAttribute & DeniedValuesAttribute * Add Base64StringAttribute. * Address feedback * Address feedback. * Reinstate culture-insensitive parsing
- Loading branch information
1 parent
8085453
commit 07f5fca
Showing
22 changed files
with
1,102 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...nentModel.Annotations/src/System/ComponentModel/DataAnnotations/AllowedValuesAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System.ComponentModel.DataAnnotations | ||
{ | ||
/// <summary> | ||
/// Specifies a list of values that should be allowed in a property. | ||
/// </summary> | ||
[CLSCompliant(false)] | ||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, | ||
AllowMultiple = false)] | ||
public class AllowedValuesAttribute : ValidationAttribute | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AllowedValuesAttribute"/> class. | ||
/// </summary> | ||
/// <param name="values"> | ||
/// A list of values that the validated value should be equal to. | ||
/// </param> | ||
public AllowedValuesAttribute(params object?[] values) | ||
{ | ||
ArgumentNullException.ThrowIfNull(values); | ||
Values = values; | ||
DefaultErrorMessage = SR.AllowedValuesAttribute_Invalid; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the list of values allowed by this attribute. | ||
/// </summary> | ||
public object?[] Values { get; } | ||
|
||
/// <summary> | ||
/// Determines whether a specified object is valid. (Overrides <see cref="ValidationAttribute.IsValid(object)" />) | ||
/// </summary> | ||
/// <param name="value">The object to validate.</param> | ||
/// <returns> | ||
/// <see langword="true" /> if any of the <see cref="Values"/> are equal to <paramref name="value"/>, | ||
/// otherwise <see langword="false" /> | ||
/// </returns> | ||
/// <remarks> | ||
/// This method can return <see langword="true"/> if the <paramref name="value" /> is <see langword="null"/>, | ||
/// provided that <see langword="null"/> is also specified in one of the <see cref="Values"/>. | ||
/// </remarks> | ||
public override bool IsValid(object? value) | ||
{ | ||
foreach (object? allowed in Values) | ||
{ | ||
if (allowed is null ? value is null : allowed.Equals(value)) | ||
{ | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/Base64StringAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Buffers; | ||
|
||
namespace System.ComponentModel.DataAnnotations | ||
{ | ||
/// <summary> | ||
/// Specifies that a data field value is a well-formed Base64 string. | ||
/// </summary> | ||
/// <remarks> | ||
/// Recognition of valid Base64 is delegated to the <see cref="Convert"/> class, | ||
/// using the <see cref="Convert.TryFromBase64String(string, Span{byte}, out int)"/> method. | ||
/// </remarks> | ||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] | ||
public class Base64StringAttribute : ValidationAttribute | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Base64StringAttribute"/> class. | ||
/// </summary> | ||
public Base64StringAttribute() | ||
{ | ||
// Set DefaultErrorMessage not ErrorMessage, allowing user to set | ||
// ErrorMessageResourceType and ErrorMessageResourceName to use localized messages. | ||
DefaultErrorMessage = SR.Base64StringAttribute_Invalid; | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether a specified object is valid. (Overrides <see cref="ValidationAttribute.IsValid(object)" />) | ||
/// </summary> | ||
/// <param name="value">The object to validate.</param> | ||
/// <returns> | ||
/// <see langword="true" /> if <paramref name="value"/> is <see langword="null"/> or is a valid Base64 string, | ||
/// otherwise <see langword="false" /> | ||
/// </returns> | ||
public override bool IsValid(object? value) | ||
{ | ||
if (value is null) | ||
{ | ||
return true; | ||
} | ||
|
||
if (value is not string valueAsString) | ||
{ | ||
return false; | ||
} | ||
|
||
byte[]? rentedBuffer = null; | ||
Span<byte> destinationBuffer = valueAsString.Length < 256 | ||
? stackalloc byte[256] | ||
: rentedBuffer = ArrayPool<byte>.Shared.Rent(valueAsString.Length); | ||
|
||
bool result = Convert.TryFromBase64String(valueAsString, destinationBuffer, out int bytesWritten); | ||
|
||
if (rentedBuffer != null) | ||
{ | ||
destinationBuffer.Slice(0, bytesWritten).Clear(); | ||
ArrayPool<byte>.Shared.Return(rentedBuffer); | ||
} | ||
|
||
return result; | ||
} | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/DeniedValuesAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System.ComponentModel.DataAnnotations | ||
{ | ||
/// <summary> | ||
/// Specifies a list of values that should not be allowed in a property. | ||
/// </summary> | ||
[CLSCompliant(false)] | ||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, | ||
AllowMultiple = false)] | ||
public class DeniedValuesAttribute : ValidationAttribute | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DeniedValuesAttribute"/> class. | ||
/// </summary> | ||
/// <param name="values"> | ||
/// A list of values that the validated value should not be equal to. | ||
/// </param> | ||
public DeniedValuesAttribute(params object?[] values) | ||
{ | ||
ArgumentNullException.ThrowIfNull(values); | ||
Values = values; | ||
DefaultErrorMessage = SR.DeniedValuesAttribute_Invalid; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the list of values denied by this attribute. | ||
/// </summary> | ||
public object?[] Values { get; } | ||
|
||
/// <summary> | ||
/// Determines whether a specified object is valid. (Overrides <see cref="ValidationAttribute.IsValid(object)" />) | ||
/// </summary> | ||
/// <param name="value">The object to validate.</param> | ||
/// <returns> | ||
/// <see langword="true" /> if none of the <see cref="Values"/> are equal to <paramref name="value"/>, | ||
/// otherwise <see langword="false" />. | ||
/// </returns> | ||
/// <remarks> | ||
/// This method can return <see langword="true"/> if the <paramref name="value" /> is <see langword="null"/>, | ||
/// provided that <see langword="null"/> is not specified in any of the <see cref="Values"/>. | ||
/// </remarks> | ||
public override bool IsValid(object? value) | ||
{ | ||
foreach (object? allowed in Values) | ||
{ | ||
if (allowed is null ? value is null : allowed.Equals(value)) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
} | ||
} |
Oops, something went wrong.