1 #region License 2 // Copyright (c) 2007 James Newton-King 3 // 4 // Permission is hereby granted, free of charge, to any person 5 // obtaining a copy of this software and associated documentation 6 // files (the "Software"), to deal in the Software without 7 // restriction, including without limitation the rights to use, 8 // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the 10 // Software is furnished to do so, subject to the following 11 // conditions: 12 // 13 // The above copyright notice and this permission notice shall be 14 // included in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 // OTHER DEALINGS IN THE SOFTWARE. 24 #endregion 25 26 using System; 27 using System.Reflection; 28 using System.Runtime.Serialization; 29 using Newtonsoft.Json.Utilities; 30 #if NETFX_CORE 31 using IConvertible = Newtonsoft.Json.Utilities.Convertible; 32 #endif 33 34 namespace Newtonsoft.Json.Serialization 35 { 36 internal enum JsonContractType 37 { 38 None, 39 Object, 40 Array, 41 Primitive, 42 String, 43 Dictionary, 44 #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE) 45 Dynamic, 46 #endif 47 #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) 48 Serializable, 49 #endif 50 Linq 51 } 52 53 /// <summary> 54 /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>. 55 /// </summary> 56 public abstract class JsonContract 57 { 58 internal bool IsNullable; 59 internal bool IsConvertable; 60 internal Type NonNullableUnderlyingType; 61 internal ReadType InternalReadType; 62 internal JsonContractType ContractType; 63 64 /// <summary> 65 /// Gets the underlying type for the contract. 66 /// </summary> 67 /// <value>The underlying type for the contract.</value> 68 public Type UnderlyingType { get; private set; } 69 70 /// <summary> 71 /// Gets or sets the type created during deserialization. 72 /// </summary> 73 /// <value>The type created during deserialization.</value> 74 public Type CreatedType { get; set; } 75 76 /// <summary> 77 /// Gets or sets whether this type contract is serialized as a reference. 78 /// </summary> 79 /// <value>Whether this type contract is serialized as a reference.</value> 80 public bool? IsReference { get; set; } 81 82 /// <summary> 83 /// Gets or sets the default <see cref="JsonConverter" /> for this contract. 84 /// </summary> 85 /// <value>The converter.</value> 86 public JsonConverter Converter { get; set; } 87 88 // internally specified JsonConverter's to override default behavour 89 // checked for after passed in converters and attribute specified converters 90 internal JsonConverter InternalConverter { get; set; } 91 92 #if !PocketPC 93 /// <summary> 94 /// Gets or sets the method called immediately after deserialization of the object. 95 /// </summary> 96 /// <value>The method called immediately after deserialization of the object.</value> 97 public MethodInfo OnDeserialized { get; set; } 98 99 /// <summary> 100 /// Gets or sets the method called during deserialization of the object. 101 /// </summary> 102 /// <value>The method called during deserialization of the object.</value> 103 public MethodInfo OnDeserializing { get; set; } 104 105 /// <summary> 106 /// Gets or sets the method called after serialization of the object graph. 107 /// </summary> 108 /// <value>The method called after serialization of the object graph.</value> 109 public MethodInfo OnSerialized { get; set; } 110 111 /// <summary> 112 /// Gets or sets the method called before serialization of the object. 113 /// </summary> 114 /// <value>The method called before serialization of the object.</value> 115 public MethodInfo OnSerializing { get; set; } 116 #endif 117 118 /// <summary> 119 /// Gets or sets the default creator method used to create the object. 120 /// </summary> 121 /// <value>The default creator method used to create the object.</value> 122 public Func<object> DefaultCreator { get; set; } 123 124 /// <summary> 125 /// Gets or sets a value indicating whether the default creator is non public. 126 /// </summary> 127 /// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value> 128 public bool DefaultCreatorNonPublic { get; set; } 129 130 /// <summary> 131 /// Gets or sets the method called when an error is thrown during the serialization of the object. 132 /// </summary> 133 /// <value>The method called when an error is thrown during the serialization of the object.</value> 134 public MethodInfo OnError { get; set; } 135 InvokeOnSerializing(object o, StreamingContext context)136 internal void InvokeOnSerializing(object o, StreamingContext context) 137 { 138 #if !PocketPC 139 if (OnSerializing != null) 140 OnSerializing.Invoke(o, new object[] {context}); 141 #endif 142 } 143 InvokeOnSerialized(object o, StreamingContext context)144 internal void InvokeOnSerialized(object o, StreamingContext context) 145 { 146 #if !PocketPC 147 if (OnSerialized != null) 148 OnSerialized.Invoke(o, new object[] {context}); 149 #endif 150 } 151 InvokeOnDeserializing(object o, StreamingContext context)152 internal void InvokeOnDeserializing(object o, StreamingContext context) 153 { 154 #if !PocketPC 155 if (OnDeserializing != null) 156 OnDeserializing.Invoke(o, new object[] {context}); 157 #endif 158 } 159 InvokeOnDeserialized(object o, StreamingContext context)160 internal void InvokeOnDeserialized(object o, StreamingContext context) 161 { 162 #if !PocketPC 163 if (OnDeserialized != null) 164 OnDeserialized.Invoke(o, new object[] {context}); 165 #endif 166 } 167 InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)168 internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext) 169 { 170 if (OnError != null) 171 OnError.Invoke(o, new object[] {context, errorContext}); 172 } 173 JsonContract(Type underlyingType)174 internal JsonContract(Type underlyingType) 175 { 176 ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType"); 177 178 UnderlyingType = underlyingType; 179 180 IsNullable = ReflectionUtils.IsNullable(underlyingType); 181 NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType; 182 183 CreatedType = NonNullableUnderlyingType; 184 185 IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType); 186 187 if (NonNullableUnderlyingType == typeof(byte[])) 188 { 189 InternalReadType = ReadType.ReadAsBytes; 190 } 191 else if (NonNullableUnderlyingType == typeof(int)) 192 { 193 InternalReadType = ReadType.ReadAsInt32; 194 } 195 else if (NonNullableUnderlyingType == typeof(decimal)) 196 { 197 InternalReadType = ReadType.ReadAsDecimal; 198 } 199 else if (NonNullableUnderlyingType == typeof(string)) 200 { 201 InternalReadType = ReadType.ReadAsString; 202 } 203 else if (NonNullableUnderlyingType == typeof(DateTime)) 204 { 205 InternalReadType = ReadType.ReadAsDateTime; 206 } 207 #if !NET20 208 else if (NonNullableUnderlyingType == typeof(DateTimeOffset)) 209 { 210 InternalReadType = ReadType.ReadAsDateTimeOffset; 211 } 212 #endif 213 else 214 { 215 InternalReadType = ReadType.Read; 216 } 217 } 218 } 219 }