Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 015cf5d

Browse files
JonHannaajcvickers
authored andcommitted
Allow RangeAttribute use to request InvariantCulture conversions. (#25918)
* Allow RangeAttribute use to request InvariantCulture conversions. Adds a ParseLimitsInInvariantCulture that affects the interpretation of the extrema set, and ConvertValueInInvariantCulture that affects the interpretation of values. Separate methods allows for e.g. a component assuming a dot-decimal-separator culture defining a property with the attribute (so invariant culture should be used) the use of the property is done in a comma-decimal-separator (so the current culture should be used), or any permutation of the two booleans. Fixes #2648 * Skip NetFX on associated tests. * Update tests in #25918 to work with changes from #26050
1 parent 472c3d9 commit 015cf5d

File tree

3 files changed

+698
-3
lines changed

3 files changed

+698
-3
lines changed

src/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,11 @@ public partial class RangeAttribute : System.ComponentModel.DataAnnotations.Vali
204204
public RangeAttribute(double minimum, double maximum) { }
205205
public RangeAttribute(int minimum, int maximum) { }
206206
public RangeAttribute(System.Type type, string minimum, string maximum) { }
207+
public bool ConvertValueInInvariantCulture { get { throw null; } set { } }
207208
public object Maximum { get { throw null; } }
208209
public object Minimum { get { throw null; } }
209210
public System.Type OperandType { get { throw null; } }
211+
public bool ParseLimitsInInvariantCulture { get { throw null; } set { } }
210212
public override string FormatErrorMessage(string name) { throw null; }
211213
public override bool IsValid(object value) { throw null; }
212214
}

src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RangeAttribute.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ public RangeAttribute(Type type, string minimum, string maximum)
7070
/// </summary>
7171
public Type OperandType { get; }
7272

73+
/// <summary>
74+
/// Determines whether string values for <see cref="Minimum"/> and <see cref="Maximum"/> are parsed in the invariant
75+
/// culture rather than the current culture in effect at the time of the validation.
76+
/// </summary>
77+
public bool ParseLimitsInInvariantCulture { get; set; }
78+
79+
/// <summary>
80+
/// Determines whether any conversions necessary from the value being validated to <see cref="OperandType"/> as set
81+
/// by the <c>type</c> parameter of the <see cref="RangeAttribute(Type, string, string)"/> constructor are carried
82+
/// out in the invariant culture rather than the current culture in effect at the time of the validation.
83+
/// </summary>
84+
/// <remarks>This property has no effects with the constructors with <see cref="int"/> or <see cref="double"/>
85+
/// parameters, for which the invariant culture is always used for any conversions of the validated value.</remarks>
86+
public bool ConvertValueInInvariantCulture { get; set; }
87+
7388
private Func<object, object> Conversion { get; set; }
7489

7590
private void Initialize(IComparable minimum, IComparable maximum, Func<object, object> conversion)
@@ -192,10 +207,25 @@ private void SetupConversion()
192207
}
193208

194209
TypeConverter converter = TypeDescriptor.GetConverter(type);
195-
IComparable min = (IComparable)converter.ConvertFromString((string)minimum);
196-
IComparable max = (IComparable)converter.ConvertFromString((string)maximum);
210+
IComparable min = (IComparable)(ParseLimitsInInvariantCulture
211+
? converter.ConvertFromInvariantString((string)minimum)
212+
: converter.ConvertFromString((string)minimum));
213+
IComparable max = (IComparable)(ParseLimitsInInvariantCulture
214+
? converter.ConvertFromInvariantString((string)maximum)
215+
: converter.ConvertFromString((string)maximum));
216+
217+
Func<object, object> conversion;
218+
if (ConvertValueInInvariantCulture)
219+
{
220+
conversion = value => value?.GetType() == type
221+
? value
222+
: converter.ConvertFrom(null, CultureInfo.InvariantCulture, value);
223+
}
224+
else
225+
{
226+
conversion = value => value?.GetType() == type ? value : converter.ConvertFrom(value);
227+
}
197228

198-
Func<object, object> conversion = value => (value != null && value.GetType() == type) ? value : converter.ConvertFrom(value);
199229
Initialize(min, max, conversion);
200230
}
201231
}

0 commit comments

Comments
 (0)