1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
5 namespace System.Runtime.Serialization.Json
7 using System.Threading;
11 class JsonCollectionDataContract : JsonDataContract
13 [Fx.Tag.SecurityNote(Critical = "Holds instance of CriticalHelper which keeps state that is cached statically for serialization."
14 + "Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
16 JsonCollectionDataContractCriticalHelper helper;
18 [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
19 Safe = "Doesn't leak anything.")]
20 [SecuritySafeCritical]
21 public JsonCollectionDataContract(CollectionDataContract traditionalDataContract)
22 : base(new JsonCollectionDataContractCriticalHelper(traditionalDataContract))
24 this.helper = base.Helper as JsonCollectionDataContractCriticalHelper;
27 internal JsonFormatCollectionReaderDelegate JsonFormatReaderDelegate
29 [Fx.Tag.SecurityNote(Critical = "Fetches the critical JsonFormatReaderDelegate property.",
30 Safe = "JsonFormatReaderDelegate only needs to be protected for write.")]
31 [SecuritySafeCritical]
34 if (helper.JsonFormatReaderDelegate == null)
38 if (helper.JsonFormatReaderDelegate == null)
40 if (TraditionalCollectionDataContract.IsReadOnlyContract)
42 DataContract.ThrowInvalidDataContractException(TraditionalCollectionDataContract.DeserializationExceptionMessage, null /*type*/);
44 JsonFormatCollectionReaderDelegate tempDelegate = new JsonFormatReaderGenerator().GenerateCollectionReader(TraditionalCollectionDataContract);
45 Thread.MemoryBarrier();
46 helper.JsonFormatReaderDelegate = tempDelegate;
50 return helper.JsonFormatReaderDelegate;
54 internal JsonFormatGetOnlyCollectionReaderDelegate JsonFormatGetOnlyReaderDelegate
56 [Fx.Tag.SecurityNote(Critical = "Fetches the critical JsonFormatGetOnlyReaderDelegate property.",
57 Safe = "JsonFormatGetOnlyReaderDelegate only needs to be protected for write; initialized in getter if null.")]
58 [SecuritySafeCritical]
61 if (helper.JsonFormatGetOnlyReaderDelegate == null)
65 if (helper.JsonFormatGetOnlyReaderDelegate == null)
67 CollectionKind kind = this.TraditionalCollectionDataContract.Kind;
68 if (this.TraditionalDataContract.UnderlyingType.IsInterface && (kind == CollectionKind.Enumerable || kind == CollectionKind.Collection || kind == CollectionKind.GenericEnumerable))
70 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GetOnlyCollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(this.TraditionalDataContract.UnderlyingType))));
72 if (TraditionalCollectionDataContract.IsReadOnlyContract)
74 DataContract.ThrowInvalidDataContractException(TraditionalCollectionDataContract.DeserializationExceptionMessage, null /*type*/);
76 JsonFormatGetOnlyCollectionReaderDelegate tempDelegate = new JsonFormatReaderGenerator().GenerateGetOnlyCollectionReader(TraditionalCollectionDataContract);
77 Thread.MemoryBarrier();
78 helper.JsonFormatGetOnlyReaderDelegate = tempDelegate;
82 return helper.JsonFormatGetOnlyReaderDelegate;
86 internal JsonFormatCollectionWriterDelegate JsonFormatWriterDelegate
88 [Fx.Tag.SecurityNote(Critical = "Fetches the critical JsonFormatWriterDelegate property.",
89 Safe = "JsonFormatWriterDelegate only needs to be protected for write.")]
90 [SecuritySafeCritical]
93 if (helper.JsonFormatWriterDelegate == null)
97 if (helper.JsonFormatWriterDelegate == null)
99 JsonFormatCollectionWriterDelegate tempDelegate = new JsonFormatWriterGenerator().GenerateCollectionWriter(TraditionalCollectionDataContract);
100 Thread.MemoryBarrier();
101 helper.JsonFormatWriterDelegate = tempDelegate;
105 return helper.JsonFormatWriterDelegate;
109 CollectionDataContract TraditionalCollectionDataContract
111 [Fx.Tag.SecurityNote(Critical = "Fetches the critical TraditionalCollectionDataContract property.",
112 Safe = "TraditionalCollectionDataContract only needs to be protected for write.")]
113 [SecuritySafeCritical]
114 get { return this.helper.TraditionalCollectionDataContract; }
117 public override object ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context)
121 if (context.IsGetOnlyCollection)
123 // IsGetOnlyCollection value has already been used to create current collectiondatacontract, value can now be reset.
124 context.IsGetOnlyCollection = false;
125 JsonFormatGetOnlyReaderDelegate(jsonReader, context, XmlDictionaryString.Empty, JsonGlobals.itemDictionaryString, TraditionalCollectionDataContract);
129 o = JsonFormatReaderDelegate(jsonReader, context, XmlDictionaryString.Empty, JsonGlobals.itemDictionaryString, TraditionalCollectionDataContract);
131 jsonReader.ReadEndElement();
135 public override void WriteJsonValueCore(XmlWriterDelegator jsonWriter, object obj, XmlObjectSerializerWriteContextComplexJson context, RuntimeTypeHandle declaredTypeHandle)
137 // IsGetOnlyCollection value has already been used to create current collectiondatacontract, value can now be reset.
138 context.IsGetOnlyCollection = false;
139 JsonFormatWriterDelegate(jsonWriter, obj, context, TraditionalCollectionDataContract);
142 [Fx.Tag.SecurityNote(Critical = "Holds all state used for (de)serializing types."
143 + "Since the data is cached statically, we lock down access to it.")]
144 #if !NO_SECURITY_ATTRIBUTES
145 #pragma warning disable 618 // have not moved to the v4 security model yet
146 [SecurityCritical(SecurityCriticalScope.Everything)]
147 #pragma warning restore 618
149 class JsonCollectionDataContractCriticalHelper : JsonDataContractCriticalHelper
151 JsonFormatCollectionReaderDelegate jsonFormatReaderDelegate;
152 JsonFormatGetOnlyCollectionReaderDelegate jsonFormatGetOnlyReaderDelegate;
153 JsonFormatCollectionWriterDelegate jsonFormatWriterDelegate;
154 CollectionDataContract traditionalCollectionDataContract;
156 public JsonCollectionDataContractCriticalHelper(CollectionDataContract traditionalDataContract)
157 : base(traditionalDataContract)
159 this.traditionalCollectionDataContract = traditionalDataContract;
162 internal JsonFormatCollectionReaderDelegate JsonFormatReaderDelegate
164 get { return this.jsonFormatReaderDelegate; }
165 set { this.jsonFormatReaderDelegate = value; }
168 internal JsonFormatGetOnlyCollectionReaderDelegate JsonFormatGetOnlyReaderDelegate
170 get { return this.jsonFormatGetOnlyReaderDelegate; }
171 set { this.jsonFormatGetOnlyReaderDelegate = value; }
174 internal JsonFormatCollectionWriterDelegate JsonFormatWriterDelegate
176 get { return this.jsonFormatWriterDelegate; }
177 set { this.jsonFormatWriterDelegate = value; }
180 internal CollectionDataContract TraditionalCollectionDataContract
182 get { return this.traditionalCollectionDataContract; }