1
/* ****************************************************************************
3 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * This software is subject to the Microsoft Public License (Ms-PL).
6 * A copy of the license can be found in the license.htm file included
7 * in this distribution.
9 * You must not remove this notice, or any other, from this software.
11 * ***************************************************************************/
13 namespace System
.Web
.Mvc
{
15 using System
.Collections
;
16 using System
.ComponentModel
;
17 using System
.Globalization
;
18 using System
.Web
.Mvc
.Resources
;
21 public class ValueProviderResult
{
23 private static readonly CultureInfo _staticCulture
= CultureInfo
.InvariantCulture
;
24 private CultureInfo _instanceCulture
;
26 // default constructor so that subclassed types can set the properties themselves
27 protected ValueProviderResult() {
30 public ValueProviderResult(object rawValue
, string attemptedValue
, CultureInfo culture
) {
32 AttemptedValue
= attemptedValue
;
36 public string AttemptedValue
{
41 public CultureInfo Culture
{
43 if (_instanceCulture
== null) {
44 _instanceCulture
= _staticCulture
;
46 return _instanceCulture
;
49 _instanceCulture
= value;
53 public object RawValue
{
58 private static object ConvertSimpleType(CultureInfo culture
, object value, Type destinationType
) {
59 if (value == null || destinationType
.IsInstanceOfType(value)) {
63 // if this is a user-input value but the user didn't type anything, return no value
64 string valueAsString
= value as string;
65 if (valueAsString
!= null && valueAsString
.Length
== 0) {
69 TypeConverter converter
= TypeDescriptor
.GetConverter(destinationType
);
70 bool canConvertFrom
= converter
.CanConvertFrom(value.GetType());
71 if (!canConvertFrom
) {
72 converter
= TypeDescriptor
.GetConverter(value.GetType());
74 if (!(canConvertFrom
|| converter
.CanConvertTo(destinationType
))) {
75 string message
= String
.Format(CultureInfo
.CurrentUICulture
, MvcResources
.ValueProviderResult_NoConverterExists
,
76 value.GetType().FullName
, destinationType
.FullName
);
77 throw new InvalidOperationException(message
);
81 object convertedValue
= (canConvertFrom
) ?
82 converter
.ConvertFrom(null /* context */, culture
, value) :
83 converter
.ConvertTo(null /* context */, culture
, value, destinationType
);
84 return convertedValue
;
86 catch (Exception ex
) {
87 string message
= String
.Format(CultureInfo
.CurrentUICulture
, MvcResources
.ValueProviderResult_ConversionThrew
,
88 value.GetType().FullName
, destinationType
.FullName
);
89 throw new InvalidOperationException(message
, ex
);
93 public object ConvertTo(Type type
) {
94 return ConvertTo(type
, null /* culture */);
97 public virtual object ConvertTo(Type type
, CultureInfo culture
) {
99 throw new ArgumentNullException("type");
102 CultureInfo cultureToUse
= culture
?? Culture
;
103 return UnwrapPossibleArrayType(cultureToUse
, RawValue
, type
);
106 private static object UnwrapPossibleArrayType(CultureInfo culture
, object value, Type destinationType
) {
107 if (value == null || destinationType
.IsInstanceOfType(value)) {
111 // array conversion results in four cases, as below
112 Array valueAsArray
= value as Array
;
113 if (destinationType
.IsArray
) {
114 Type destinationElementType
= destinationType
.GetElementType();
115 if (valueAsArray
!= null) {
116 // case 1: both destination + source type are arrays, so convert each element
117 IList converted
= Array
.CreateInstance(destinationElementType
, valueAsArray
.Length
);
118 for (int i
= 0; i
< valueAsArray
.Length
; i
++) {
119 converted
[i
] = ConvertSimpleType(culture
, valueAsArray
.GetValue(i
), destinationElementType
);
124 // case 2: destination type is array but source is single element, so wrap element in array + convert
125 object element
= ConvertSimpleType(culture
, value, destinationElementType
);
126 IList converted
= Array
.CreateInstance(destinationElementType
, 1);
127 converted
[0] = element
;
131 else if (valueAsArray
!= null) {
132 // case 3: destination type is single element but source is array, so extract first element + convert
133 if (valueAsArray
.Length
> 0) {
134 value = valueAsArray
.GetValue(0);
135 return ConvertSimpleType(culture
, value, destinationType
);
138 // case 3(a): source is empty array, so can't perform conversion
142 // case 4: both destination + source type are single elements, so convert
143 return ConvertSimpleType(culture
, value, destinationType
);