Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Web.Mvc/ValueProviderResult.cs')
-rw-r--r--src/System.Web.Mvc/ValueProviderResult.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/System.Web.Mvc/ValueProviderResult.cs b/src/System.Web.Mvc/ValueProviderResult.cs
new file mode 100644
index 00000000..3a15980b
--- /dev/null
+++ b/src/System.Web.Mvc/ValueProviderResult.cs
@@ -0,0 +1,163 @@
+using System.Collections;
+using System.ComponentModel;
+using System.Globalization;
+using System.Web.Mvc.Properties;
+
+namespace System.Web.Mvc
+{
+ [Serializable]
+ public class ValueProviderResult
+ {
+ private static readonly CultureInfo _staticCulture = CultureInfo.InvariantCulture;
+ private CultureInfo _instanceCulture;
+
+ // default constructor so that subclassed types can set the properties themselves
+ protected ValueProviderResult()
+ {
+ }
+
+ public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture)
+ {
+ RawValue = rawValue;
+ AttemptedValue = attemptedValue;
+ Culture = culture;
+ }
+
+ public string AttemptedValue { get; protected set; }
+
+ public CultureInfo Culture
+ {
+ get
+ {
+ if (_instanceCulture == null)
+ {
+ _instanceCulture = _staticCulture;
+ }
+ return _instanceCulture;
+ }
+ protected set { _instanceCulture = value; }
+ }
+
+ public object RawValue { get; protected set; }
+
+ private static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType)
+ {
+ if (value == null || destinationType.IsInstanceOfType(value))
+ {
+ return value;
+ }
+
+ // if this is a user-input value but the user didn't type anything, return no value
+ string valueAsString = value as string;
+ if (valueAsString != null && valueAsString.Trim().Length == 0)
+ {
+ return null;
+ }
+
+ TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
+ bool canConvertFrom = converter.CanConvertFrom(value.GetType());
+ if (!canConvertFrom)
+ {
+ converter = TypeDescriptor.GetConverter(value.GetType());
+ }
+ if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
+ {
+ // EnumConverter cannot convert integer, so we verify manually
+ if (destinationType.IsEnum && value is int)
+ {
+ return Enum.ToObject(destinationType, (int)value);
+ }
+
+ // In case of a Nullable object, we try again with its underlying type.
+ Type underlyingType = Nullable.GetUnderlyingType(destinationType);
+ if (underlyingType != null)
+ {
+ return ConvertSimpleType(culture, value, underlyingType);
+ }
+
+ string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_NoConverterExists,
+ value.GetType().FullName, destinationType.FullName);
+ throw new InvalidOperationException(message);
+ }
+
+ try
+ {
+ object convertedValue = (canConvertFrom)
+ ? converter.ConvertFrom(null /* context */, culture, value)
+ : converter.ConvertTo(null /* context */, culture, value, destinationType);
+ return convertedValue;
+ }
+ catch (Exception ex)
+ {
+ string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_ConversionThrew,
+ value.GetType().FullName, destinationType.FullName);
+ throw new InvalidOperationException(message, ex);
+ }
+ }
+
+ public object ConvertTo(Type type)
+ {
+ return ConvertTo(type, null /* culture */);
+ }
+
+ public virtual object ConvertTo(Type type, CultureInfo culture)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ CultureInfo cultureToUse = culture ?? Culture;
+ return UnwrapPossibleArrayType(cultureToUse, RawValue, type);
+ }
+
+ private static object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType)
+ {
+ if (value == null || destinationType.IsInstanceOfType(value))
+ {
+ return value;
+ }
+
+ // array conversion results in four cases, as below
+ Array valueAsArray = value as Array;
+ if (destinationType.IsArray)
+ {
+ Type destinationElementType = destinationType.GetElementType();
+ if (valueAsArray != null)
+ {
+ // case 1: both destination + source type are arrays, so convert each element
+ IList converted = Array.CreateInstance(destinationElementType, valueAsArray.Length);
+ for (int i = 0; i < valueAsArray.Length; i++)
+ {
+ converted[i] = ConvertSimpleType(culture, valueAsArray.GetValue(i), destinationElementType);
+ }
+ return converted;
+ }
+ else
+ {
+ // case 2: destination type is array but source is single element, so wrap element in array + convert
+ object element = ConvertSimpleType(culture, value, destinationElementType);
+ IList converted = Array.CreateInstance(destinationElementType, 1);
+ converted[0] = element;
+ return converted;
+ }
+ }
+ else if (valueAsArray != null)
+ {
+ // case 3: destination type is single element but source is array, so extract first element + convert
+ if (valueAsArray.Length > 0)
+ {
+ value = valueAsArray.GetValue(0);
+ return ConvertSimpleType(culture, value, destinationType);
+ }
+ else
+ {
+ // case 3(a): source is empty array, so can't perform conversion
+ return null;
+ }
+ }
+ // case 4: both destination + source type are single elements, so convert
+ return ConvertSimpleType(culture, value, destinationType);
+ }
+ }
+}