-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Open
Labels
api-needs-workAPI needs work before it is approved, it is NOT ready for implementationAPI needs work before it is approved, it is NOT ready for implementationarea-System.ComponentModel.DataAnnotationspartner-impactThis issue impacts a partner who needs to be kept updatedThis issue impacts a partner who needs to be kept updated
Milestone
Description
Background and motivation
The RangeAttribute currently supports int and double ranges out of the box using dedicated constructor overloads, however any other range necessitates using this overload requiring the operand type as well as string formatted representations of the lower and upper bounds. This only works for types supported by the TypeConverter class expressing limits in strings forces concerns around culture-sensitive formatting:
public class TimeSpanRangeAttribute : RangeAttribute
{
public TimeSpanRangeAttribute(int minMilliseconds, int maxMilliseconds)
: base(type: typeof(TimeSpan),
minimum: TimeSpan.FromMilliseconds(minMilliseconds).ToString("c"),
maximum: TimeSpan.FromMilliseconds(maxMilliseconds).ToString("c"))
{
ParseLimitsInInvariantCulture = true;
}
}I've been working on a prototype that adds a protected constructor which accepts arbitrary IComparable bounds directly.
API Proposal
namespace System.ComponentModel.DataAnnotations;
public partial class RangeAttribute
{
public RangeAttribute(int minimum, int maximum);
public RangeAttribute(double minimum, double maximum);
+ public RangeAttribute(IComparable minimum, IComparable maximum);
[RequiresUnreferencedCode("Generic TypeConverters may require the generic types to be annotated.")]
public RangeAttribute(Type type, string minimum, string maximum);
}API Usage
The above example is now rendered as follows:
public class TimeSpanMillisecondRangeAttribute : RangeAttribute
{
public TimeSpanMillisecondRangeAttribute(int minimumMs, int maximumMs)
: base(TimeSpan.FromMilliseconds(minimumMs), TimeSpan.FromMilliseconds(maximumMs))
{ }
}Alternative Designs
- I marked the proposed constructor as
protected, since marking it public would add OOTB support for things like string or long ranges using their built-in IComparable implementation. Marking itprotectedemphasizes its use as an extensibility point for user-defined derived validation attributes. If people thinks it is useful, we could mark aspublicinstead. - Proposal leaves out
IComparersupport since the validator implementation is oriented around handling ofIComparablevalues.
Risks
No response
jeffhandley
Metadata
Metadata
Assignees
Labels
api-needs-workAPI needs work before it is approved, it is NOT ready for implementationAPI needs work before it is approved, it is NOT ready for implementationarea-System.ComponentModel.DataAnnotationspartner-impactThis issue impacts a partner who needs to be kept updatedThis issue impacts a partner who needs to be kept updated