XmlObjectSerializerReadContextComplexJson.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.Runtime.Serialization.Json
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Runtime;
  9. using System.Security;
  10. using System.ServiceModel;
  11. using System.Text;
  12. using System.Xml;
  13. #if USE_REFEMIT
  14. public class XmlObjectSerializerReadContextComplexJson : XmlObjectSerializerReadContextComplex
  15. #else
  16. class XmlObjectSerializerReadContextComplexJson : XmlObjectSerializerReadContextComplex
  17. #endif
  18. {
  19. string extensionDataValueType;
  20. DateTimeFormat dateTimeFormat;
  21. bool useSimpleDictionaryFormat;
  22. public XmlObjectSerializerReadContextComplexJson(DataContractJsonSerializer serializer, DataContract rootTypeDataContract)
  23. : base(serializer, serializer.MaxItemsInObjectGraph,
  24. new StreamingContext(StreamingContextStates.All),
  25. serializer.IgnoreExtensionDataObject)
  26. {
  27. this.rootTypeDataContract = rootTypeDataContract;
  28. this.serializerKnownTypeList = serializer.knownTypeList;
  29. this.dataContractSurrogate = serializer.DataContractSurrogate;
  30. this.dateTimeFormat = serializer.DateTimeFormat;
  31. this.useSimpleDictionaryFormat = serializer.UseSimpleDictionaryFormat;
  32. }
  33. internal IList<Type> SerializerKnownTypeList
  34. {
  35. get
  36. {
  37. return this.serializerKnownTypeList;
  38. }
  39. }
  40. public bool UseSimpleDictionaryFormat
  41. {
  42. get
  43. {
  44. return this.useSimpleDictionaryFormat;
  45. }
  46. }
  47. protected override void StartReadExtensionDataValue(XmlReaderDelegator xmlReader)
  48. {
  49. extensionDataValueType = xmlReader.GetAttribute(JsonGlobals.typeString);
  50. }
  51. protected override IDataNode ReadPrimitiveExtensionDataValue(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
  52. {
  53. IDataNode dataNode;
  54. switch (extensionDataValueType)
  55. {
  56. case null:
  57. case JsonGlobals.stringString:
  58. dataNode = new DataNode<string>(xmlReader.ReadContentAsString());
  59. break;
  60. case JsonGlobals.booleanString:
  61. dataNode = new DataNode<bool>(xmlReader.ReadContentAsBoolean());
  62. break;
  63. case JsonGlobals.numberString:
  64. dataNode = ReadNumericalPrimitiveExtensionDataValue(xmlReader);
  65. break;
  66. default:
  67. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
  68. XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.JsonUnexpectedAttributeValue, extensionDataValueType)));
  69. }
  70. xmlReader.ReadEndElement();
  71. return dataNode;
  72. }
  73. IDataNode ReadNumericalPrimitiveExtensionDataValue(XmlReaderDelegator xmlReader)
  74. {
  75. TypeCode type;
  76. object numericalValue = JsonObjectDataContract.ParseJsonNumber(xmlReader.ReadContentAsString(), out type);
  77. switch (type)
  78. {
  79. case TypeCode.Byte:
  80. return new DataNode<byte>((byte)numericalValue);
  81. case TypeCode.SByte:
  82. return new DataNode<sbyte>((sbyte)numericalValue);
  83. case TypeCode.Int16:
  84. return new DataNode<short>((short)numericalValue);
  85. case TypeCode.Int32:
  86. return new DataNode<int>((int)numericalValue);
  87. case TypeCode.Int64:
  88. return new DataNode<long>((long)numericalValue);
  89. case TypeCode.UInt16:
  90. return new DataNode<ushort>((ushort)numericalValue);
  91. case TypeCode.UInt32:
  92. return new DataNode<uint>((uint)numericalValue);
  93. case TypeCode.UInt64:
  94. return new DataNode<ulong>((ulong)numericalValue);
  95. case TypeCode.Single:
  96. return new DataNode<float>((float)numericalValue);
  97. case TypeCode.Double:
  98. return new DataNode<double>((double)numericalValue);
  99. case TypeCode.Decimal:
  100. return new DataNode<decimal>((decimal)numericalValue);
  101. default:
  102. throw Fx.AssertAndThrow("JsonObjectDataContract.ParseJsonNumber shouldn't return a TypeCode that we're not expecting");
  103. }
  104. }
  105. internal static XmlObjectSerializerReadContextComplexJson CreateContext(DataContractJsonSerializer serializer, DataContract rootTypeDataContract)
  106. {
  107. return new XmlObjectSerializerReadContextComplexJson(serializer, rootTypeDataContract);
  108. }
  109. #if USE_REFEMIT
  110. public override int GetArraySize()
  111. #else
  112. internal override int GetArraySize()
  113. #endif
  114. {
  115. return -1;
  116. }
  117. protected override object ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
  118. {
  119. return DataContractJsonSerializer.ReadJsonValue(dataContract, reader, this);
  120. }
  121. #if USE_REFEMIT
  122. public override void ReadAttributes(XmlReaderDelegator xmlReader)
  123. #else
  124. internal override void ReadAttributes(XmlReaderDelegator xmlReader)
  125. #endif
  126. {
  127. if (attributes == null)
  128. attributes = new Attributes();
  129. attributes.Reset();
  130. if (xmlReader.MoveToAttribute(JsonGlobals.typeString) && xmlReader.Value == JsonGlobals.nullString)
  131. {
  132. attributes.XsiNil = true;
  133. }
  134. else if (xmlReader.MoveToAttribute(JsonGlobals.serverTypeString))
  135. {
  136. XmlQualifiedName qualifiedTypeName = JsonReaderDelegator.ParseQualifiedName(xmlReader.Value);
  137. attributes.XsiTypeName = qualifiedTypeName.Name;
  138. string serverTypeNamespace = qualifiedTypeName.Namespace;
  139. if (!string.IsNullOrEmpty(serverTypeNamespace))
  140. {
  141. switch (serverTypeNamespace[0])
  142. {
  143. case '#':
  144. serverTypeNamespace = string.Concat(Globals.DataContractXsdBaseNamespace, serverTypeNamespace.Substring(1));
  145. break;
  146. case '\\':
  147. if (serverTypeNamespace.Length >= 2)
  148. {
  149. switch (serverTypeNamespace[1])
  150. {
  151. case '#':
  152. case '\\':
  153. serverTypeNamespace = serverTypeNamespace.Substring(1);
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. break;
  160. default:
  161. break;
  162. }
  163. }
  164. attributes.XsiTypeNamespace = serverTypeNamespace;
  165. }
  166. xmlReader.MoveToElement();
  167. }
  168. public int GetJsonMemberIndex(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, int memberIndex, ExtensionDataObject extensionData)
  169. {
  170. int length = memberNames.Length;
  171. if (length != 0)
  172. {
  173. for (int i = 0, index = (memberIndex + 1) % length; i < length; i++, index = (index + 1) % length)
  174. {
  175. if (xmlReader.IsStartElement(memberNames[index], XmlDictionaryString.Empty))
  176. {
  177. return index;
  178. }
  179. }
  180. string name;
  181. if (TryGetJsonLocalName(xmlReader, out name))
  182. {
  183. for (int i = 0, index = (memberIndex + 1) % length; i < length; i++, index = (index + 1) % length)
  184. {
  185. if (memberNames[index].Value == name)
  186. {
  187. return index;
  188. }
  189. }
  190. }
  191. }
  192. HandleMemberNotFound(xmlReader, extensionData, memberIndex);
  193. return length;
  194. }
  195. internal static bool TryGetJsonLocalName(XmlReaderDelegator xmlReader, out string name)
  196. {
  197. if (xmlReader.IsStartElement(JsonGlobals.itemDictionaryString, JsonGlobals.itemDictionaryString))
  198. {
  199. if (xmlReader.MoveToAttribute(JsonGlobals.itemString))
  200. {
  201. name = xmlReader.Value;
  202. return true;
  203. }
  204. }
  205. name = null;
  206. return false;
  207. }
  208. public static string GetJsonMemberName(XmlReaderDelegator xmlReader)
  209. {
  210. string name;
  211. if (!TryGetJsonLocalName(xmlReader, out name))
  212. {
  213. name = xmlReader.LocalName;
  214. }
  215. return name;
  216. }
  217. public static void ThrowMissingRequiredMembers(object obj, XmlDictionaryString[] memberNames, byte[] expectedElements, byte[] requiredElements)
  218. {
  219. StringBuilder stringBuilder = new StringBuilder();
  220. int missingMembersCount = 0;
  221. for (int i = 0; i < memberNames.Length; i++)
  222. {
  223. if (IsBitSet(expectedElements, i) && IsBitSet(requiredElements, i))
  224. {
  225. if (stringBuilder.Length != 0)
  226. stringBuilder.Append(", ");
  227. stringBuilder.Append(memberNames[i]);
  228. missingMembersCount++;
  229. }
  230. }
  231. if (missingMembersCount == 1)
  232. {
  233. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(
  234. SR.JsonOneRequiredMemberNotFound, DataContract.GetClrTypeFullName(obj.GetType()), stringBuilder.ToString())));
  235. }
  236. else
  237. {
  238. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(
  239. SR.JsonRequiredMembersNotFound, DataContract.GetClrTypeFullName(obj.GetType()), stringBuilder.ToString())));
  240. }
  241. }
  242. public static void ThrowDuplicateMemberException(object obj, XmlDictionaryString[] memberNames, int memberIndex)
  243. {
  244. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(
  245. SR.GetString(SR.JsonDuplicateMemberInInput, DataContract.GetClrTypeFullName(obj.GetType()), memberNames[memberIndex])));
  246. }
  247. [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical helper class 'BitFlagsGenerator'.",
  248. Safe = "This method is safe to call.")]
  249. [SecuritySafeCritical]
  250. static bool IsBitSet(byte[] bytes, int bitIndex)
  251. {
  252. return BitFlagsGenerator.IsBitSet(bytes, bitIndex);
  253. }
  254. protected override bool IsReadingCollectionExtensionData(XmlReaderDelegator xmlReader)
  255. {
  256. return xmlReader.GetAttribute(JsonGlobals.typeString) == JsonGlobals.arrayString;
  257. }
  258. protected override bool IsReadingClassExtensionData(XmlReaderDelegator xmlReader)
  259. {
  260. return xmlReader.GetAttribute(JsonGlobals.typeString) == JsonGlobals.objectString;
  261. }
  262. protected override XmlReaderDelegator CreateReaderDelegatorForReader(XmlReader xmlReader)
  263. {
  264. return new JsonReaderDelegator(xmlReader, this.dateTimeFormat);
  265. }
  266. internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
  267. {
  268. DataContract dataContract = base.GetDataContract(typeHandle, type);
  269. DataContractJsonSerializer.CheckIfTypeIsReference(dataContract);
  270. return dataContract;
  271. }
  272. internal override DataContract GetDataContractSkipValidation(int typeId, RuntimeTypeHandle typeHandle, Type type)
  273. {
  274. DataContract dataContract = base.GetDataContractSkipValidation(typeId, typeHandle, type);
  275. DataContractJsonSerializer.CheckIfTypeIsReference(dataContract);
  276. return dataContract;
  277. }
  278. internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
  279. {
  280. DataContract dataContract = base.GetDataContract(id, typeHandle);
  281. DataContractJsonSerializer.CheckIfTypeIsReference(dataContract);
  282. return dataContract;
  283. }
  284. protected override DataContract ResolveDataContractFromRootDataContract(XmlQualifiedName typeQName)
  285. {
  286. return XmlObjectSerializerWriteContextComplexJson.ResolveJsonDataContractFromRootDataContract(this, typeQName, rootTypeDataContract);
  287. }
  288. }
  289. }