1 //------------------------------------------------------------------------------
2 // <copyright file="XmlSerializer.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 namespace System
.Xml
.Serialization
{
10 using System
.Reflection
;
11 using System
.Collections
;
13 using System
.Xml
.Schema
;
16 using System
.Threading
;
17 using System
.Globalization
;
18 using System
.Security
;
19 using System
.Security
.Permissions
;
20 using System
.Security
.Policy
;
21 using System
.Xml
.Serialization
.Configuration
;
22 using System
.Diagnostics
;
23 using System
.CodeDom
.Compiler
;
24 using System
.Runtime
.Versioning
;
26 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents"]/*' />
28 /// <para>[To be supplied.]</para>
30 public struct XmlDeserializationEvents
{
31 XmlNodeEventHandler onUnknownNode
;
32 XmlAttributeEventHandler onUnknownAttribute
;
33 XmlElementEventHandler onUnknownElement
;
34 UnreferencedObjectEventHandler onUnreferencedObject
;
35 internal object sender
;
37 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownNode"]/*' />
38 public XmlNodeEventHandler OnUnknownNode
{
44 onUnknownNode
= value;
48 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownAttribute"]/*' />
49 public XmlAttributeEventHandler OnUnknownAttribute
{
51 return onUnknownAttribute
;
54 onUnknownAttribute
= value;
58 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnknownElement"]/*' />
59 public XmlElementEventHandler OnUnknownElement
{
61 return onUnknownElement
;
64 onUnknownElement
= value;
68 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlDeserializationEvents.OnUnreferencedObject"]/*' />
69 public UnreferencedObjectEventHandler OnUnreferencedObject
{
71 return onUnreferencedObject
;
74 onUnreferencedObject
= value;
79 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation"]/*' />
82 /// <para>[To be supplied.]</para>
84 public abstract class XmlSerializerImplementation
{
85 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.Reader"]/*' />
86 public virtual XmlSerializationReader Reader{ get {throw new NotSupportedException();}
}
87 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.Writer"]/*' />
88 public virtual XmlSerializationWriter Writer{ get {throw new NotSupportedException();}
}
89 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.ReadMethods"]/*' />
90 public virtual Hashtable ReadMethods{ get {throw new NotSupportedException();}
}
91 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.WriteMethods"]/*' />
92 public virtual Hashtable WriteMethods{ get {throw new NotSupportedException();}
}
93 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.TypedSerializers"]/*' />
94 public virtual Hashtable TypedSerializers{ get {throw new NotSupportedException();}
}
95 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.CanSerialize"]/*' />
96 public virtual bool CanSerialize(Type type
){ throw new NotSupportedException(); }
97 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializerImplementation.GetSerializer"]/*' />
98 public virtual XmlSerializer
GetSerializer(Type type
){ throw new NotSupportedException(); }
101 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer"]/*' />
103 /// <para>[To be supplied.]</para>
105 public class XmlSerializer
{
106 TempAssembly tempAssembly
;
107 bool typedSerializer
;
110 XmlDeserializationEvents events
= new XmlDeserializationEvents();
112 static TempAssemblyCache cache
= new TempAssemblyCache();
113 static volatile XmlSerializerNamespaces defaultNamespaces
;
114 static XmlSerializerNamespaces DefaultNamespaces
{
116 if (defaultNamespaces
== null) {
117 XmlSerializerNamespaces nss
= new XmlSerializerNamespaces();
118 nss
.AddInternal("xsi", XmlSchema
.InstanceNamespace
);
119 nss
.AddInternal("xsd", XmlSchema
.Namespace
);
120 if (defaultNamespaces
== null) {
121 defaultNamespaces
= nss
;
124 return defaultNamespaces
;
128 static Hashtable xmlSerializerTable
= new Hashtable();
130 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer8"]/*' />
132 protected XmlSerializer() {
135 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer"]/*' />
137 /// <para>[To be supplied.]</para>
139 public XmlSerializer(Type type
, XmlAttributeOverrides overrides
, Type
[] extraTypes
, XmlRootAttribute root
, string defaultNamespace
) :
140 this (type
, overrides
, extraTypes
, root
, defaultNamespace
, null) {
143 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer2"]/*' />
145 /// <para>[To be supplied.]</para>
147 public XmlSerializer(Type type
, XmlRootAttribute root
) : this(type
, null, new Type
[0], root
, null, null) {
150 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer3"]/*' />
152 /// <para>[To be supplied.]</para>
154 public XmlSerializer(Type type
, Type
[] extraTypes
) : this(type
, null, extraTypes
, null, null, null) {
157 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer4"]/*' />
159 /// <para>[To be supplied.]</para>
161 public XmlSerializer(Type type
, XmlAttributeOverrides overrides
) : this(type
, overrides
, new Type
[0], null, null, null) {
164 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer5"]/*' />
166 /// <para>[To be supplied.]</para>
168 public XmlSerializer(XmlTypeMapping xmlTypeMapping
) {
169 tempAssembly
= GenerateTempAssembly(xmlTypeMapping
);
170 this.mapping
= xmlTypeMapping
;
173 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer6"]/*' />
175 /// <para>[To be supplied.]</para>
177 public XmlSerializer(Type type
) : this(type
, (string)null) {
180 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer1"]/*' />
182 /// <para>[To be supplied.]</para>
184 public XmlSerializer(Type type
, string defaultNamespace
) {
186 throw new ArgumentNullException("type");
187 this.mapping
= GetKnownMapping(type
, defaultNamespace
);
188 if (this.mapping
!= null) {
189 this.primitiveType
= type
;
192 tempAssembly
= cache
[defaultNamespace
, type
];
193 if (tempAssembly
== null) {
195 tempAssembly
= cache
[defaultNamespace
, type
];
196 if (tempAssembly
== null) {
197 XmlSerializerImplementation contract
;
198 Assembly assembly
= TempAssembly
.LoadGeneratedAssembly(type
, defaultNamespace
, out contract
);
199 if (assembly
== null) {
200 // need to reflect and generate new serialization assembly
201 XmlReflectionImporter importer
= new XmlReflectionImporter(defaultNamespace
);
202 this.mapping
= importer
.ImportTypeMapping(type
, null, defaultNamespace
);
203 tempAssembly
= GenerateTempAssembly(this.mapping
, type
, defaultNamespace
);
206 // we found the pre-generated assembly, now make sure that the assembly has the right serializer
207 // try to avoid the reflection step, need to get ElementName, namespace and the Key form the type
208 this.mapping
= XmlReflectionImporter
.GetTopLevelMapping(type
, defaultNamespace
);
209 tempAssembly
= new TempAssembly(new XmlMapping
[] { this.mapping }
, assembly
, contract
);
212 cache
.Add(defaultNamespace
, type
, tempAssembly
);
215 if (mapping
== null) {
216 mapping
= XmlReflectionImporter
.GetTopLevelMapping(type
, defaultNamespace
);
220 public XmlSerializer(Type type
, XmlAttributeOverrides overrides
, Type
[] extraTypes
, XmlRootAttribute root
, string defaultNamespace
, string location
)
221 #pragma warning disable 618 // Passing through null evidence to keep the .ctor code centralized
222 : this (type
, overrides
, extraTypes
, root
, defaultNamespace
, location
, null) {
223 #pragma warning restore 618
226 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.XmlSerializer7"]/*' />
228 /// <para>[To be supplied.]</para>
230 [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use a XmlSerializer constructor overload which does not take an Evidence parameter. See http://go2.microsoft.com/fwlink/?LinkId=131738 for more information.")]
231 public XmlSerializer(Type type
, XmlAttributeOverrides overrides
, Type
[] extraTypes
, XmlRootAttribute root
, string defaultNamespace
, string location
, Evidence evidence
) {
233 throw new ArgumentNullException("type");
234 XmlReflectionImporter importer
= new XmlReflectionImporter(overrides
, defaultNamespace
);
235 if (extraTypes
!= null)
237 for (int i
= 0; i
< extraTypes
.Length
; i
++)
238 importer
.IncludeType(extraTypes
[i
]);
240 this.mapping
= importer
.ImportTypeMapping(type
, root
, defaultNamespace
);
241 if (location
!= null || evidence
!= null) {
242 DemandForUserLocationOrEvidence();
244 tempAssembly
= GenerateTempAssembly(this.mapping
, type
, defaultNamespace
, location
, evidence
);
247 [PermissionSet(SecurityAction
.Demand
, Name
= "FullTrust")]
248 void DemandForUserLocationOrEvidence() {
249 // Ensure full trust before asserting full file access to the user-provided location or evidence
252 internal static TempAssembly
GenerateTempAssembly(XmlMapping xmlMapping
) {
253 return GenerateTempAssembly(xmlMapping
, null, null);
256 internal static TempAssembly
GenerateTempAssembly(XmlMapping xmlMapping
, Type type
, string defaultNamespace
) {
257 if (xmlMapping
== null)
258 throw new ArgumentNullException("xmlMapping");
259 return new TempAssembly(new XmlMapping
[] { xmlMapping }
, new Type
[] {type}
, defaultNamespace
, null, null);
262 internal static TempAssembly
GenerateTempAssembly(XmlMapping xmlMapping
, Type type
, string defaultNamespace
, string location
, Evidence evidence
) {
263 return new TempAssembly(new XmlMapping
[] { xmlMapping }
, new Type
[] {type}
, defaultNamespace
, location
, evidence
);
266 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize"]/*' />
268 /// <para>[To be supplied.]</para>
270 public void Serialize(TextWriter textWriter
, object o
) {
271 Serialize(textWriter
, o
, null);
274 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize1"]/*' />
276 /// <para>[To be supplied.]</para>
278 public void Serialize(TextWriter textWriter
, object o
, XmlSerializerNamespaces namespaces
) {
279 XmlTextWriter xmlWriter
= new XmlTextWriter(textWriter
);
280 xmlWriter
.Formatting
= Formatting
.Indented
;
281 xmlWriter
.Indentation
= 2;
282 Serialize(xmlWriter
, o
, namespaces
);
285 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize2"]/*' />
287 /// <para>[To be supplied.]</para>
289 public void Serialize(Stream stream
, object o
) {
290 Serialize(stream
, o
, null);
293 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize3"]/*' />
295 /// <para>[To be supplied.]</para>
297 public void Serialize(Stream stream
, object o
, XmlSerializerNamespaces namespaces
) {
298 XmlTextWriter xmlWriter
= new XmlTextWriter(stream
, null);
299 xmlWriter
.Formatting
= Formatting
.Indented
;
300 xmlWriter
.Indentation
= 2;
301 Serialize(xmlWriter
, o
, namespaces
);
304 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize4"]/*' />
306 /// <para>[To be supplied.]</para>
308 public void Serialize(XmlWriter xmlWriter
, object o
) {
309 Serialize(xmlWriter
, o
, null);
312 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize5"]/*' />
314 /// <para>[To be supplied.]</para>
316 public void Serialize(XmlWriter xmlWriter
, object o
, XmlSerializerNamespaces namespaces
) {
317 Serialize(xmlWriter
, o
, namespaces
, null);
319 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize6"]/*' />
320 public void Serialize(XmlWriter xmlWriter
, object o
, XmlSerializerNamespaces namespaces
, string encodingStyle
) {
321 Serialize(xmlWriter
, o
, namespaces
, encodingStyle
, null);
324 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize6"]/*' />
325 public void Serialize(XmlWriter xmlWriter
, object o
, XmlSerializerNamespaces namespaces
, string encodingStyle
, string id
) {
327 if (primitiveType
!= null) {
328 if (encodingStyle
!= null && encodingStyle
.Length
> 0) {
329 throw new InvalidOperationException(Res
.GetString(Res
.XmlInvalidEncodingNotEncoded1
, encodingStyle
));
331 SerializePrimitive(xmlWriter
, o
, namespaces
);
333 else if (tempAssembly
== null || typedSerializer
) {
334 XmlSerializationWriter writer
= CreateWriter();
335 writer
.Init(xmlWriter
, namespaces
== null || namespaces
.Count
== 0 ? DefaultNamespaces
: namespaces
, encodingStyle
, id
, tempAssembly
);
337 Serialize(o
, writer
);
344 tempAssembly
.InvokeWriter(mapping
, xmlWriter
, o
, namespaces
== null || namespaces
.Count
== 0 ? DefaultNamespaces
: namespaces
, encodingStyle
, id
);
346 catch (Exception e
) {
347 if (e
is ThreadAbortException
|| e
is StackOverflowException
|| e
is OutOfMemoryException
) {
350 if (e
is TargetInvocationException
)
351 e
= e
.InnerException
;
352 throw new InvalidOperationException(Res
.GetString(Res
.XmlGenError
), e
);
357 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize"]/*' />
359 /// <para>[To be supplied.]</para>
361 public object Deserialize(Stream stream
) {
362 XmlTextReader xmlReader
= new XmlTextReader(stream
);
363 xmlReader
.WhitespaceHandling
= WhitespaceHandling
.Significant
;
364 xmlReader
.Normalization
= true;
365 xmlReader
.XmlResolver
= null;
366 return Deserialize(xmlReader
, null);
369 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize1"]/*' />
371 /// <para>[To be supplied.]</para>
373 public object Deserialize(TextReader textReader
) {
374 XmlTextReader xmlReader
= new XmlTextReader(textReader
);
375 xmlReader
.WhitespaceHandling
= WhitespaceHandling
.Significant
;
376 xmlReader
.Normalization
= true;
377 xmlReader
.XmlResolver
= null;
378 return Deserialize(xmlReader
, null);
381 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize2"]/*' />
383 /// <para>[To be supplied.]</para>
385 public object Deserialize(XmlReader xmlReader
) {
386 return Deserialize(xmlReader
, null);
389 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize3"]/*' />
390 public object Deserialize(XmlReader xmlReader
, XmlDeserializationEvents events
) {
391 return Deserialize(xmlReader
, null, events
);
394 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize4"]/*' />
395 public object Deserialize(XmlReader xmlReader
, string encodingStyle
) {
396 return Deserialize(xmlReader
, encodingStyle
, this.events
);
399 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize5"]/*' />
400 public object Deserialize(XmlReader xmlReader
, string encodingStyle
, XmlDeserializationEvents events
) {
401 events
.sender
= this;
403 if (primitiveType
!= null) {
404 if (encodingStyle
!= null && encodingStyle
.Length
> 0) {
405 throw new InvalidOperationException(Res
.GetString(Res
.XmlInvalidEncodingNotEncoded1
, encodingStyle
));
407 return DeserializePrimitive(xmlReader
, events
);
409 else if (tempAssembly
== null || typedSerializer
) {
410 XmlSerializationReader reader
= CreateReader();
411 reader
.Init(xmlReader
, events
, encodingStyle
, tempAssembly
);
413 return Deserialize(reader
);
420 return tempAssembly
.InvokeReader(mapping
, xmlReader
, events
, encodingStyle
);
423 catch (Exception e
) {
424 if (e
is ThreadAbortException
|| e
is StackOverflowException
|| e
is OutOfMemoryException
) {
427 if (e
is TargetInvocationException
)
428 e
= e
.InnerException
;
430 if (xmlReader
is IXmlLineInfo
) {
431 IXmlLineInfo lineInfo
= (IXmlLineInfo
)xmlReader
;
432 throw new InvalidOperationException(Res
.GetString(Res
.XmlSerializeErrorDetails
, lineInfo
.LineNumber
.ToString(CultureInfo
.InvariantCulture
), lineInfo
.LinePosition
.ToString(CultureInfo
.InvariantCulture
)), e
);
435 throw new InvalidOperationException(Res
.GetString(Res
.XmlSerializeError
), e
);
440 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CanDeserialize"]/*' />
442 /// <para>[To be supplied.]</para>
444 public virtual bool CanDeserialize(XmlReader xmlReader
) {
445 if (primitiveType
!= null) {
446 TypeDesc typeDesc
= (TypeDesc
)TypeScope
.PrimtiveTypes
[primitiveType
];
447 return xmlReader
.IsStartElement(typeDesc
.DataType
.Name
, string.Empty
);
449 else if (tempAssembly
!= null) {
450 return tempAssembly
.CanRead(mapping
, xmlReader
);
457 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings"]/*' />
459 /// <para>[To be supplied.]</para>
461 [PermissionSet(SecurityAction
.LinkDemand
, Name
="FullTrust")]
462 public static XmlSerializer
[] FromMappings(XmlMapping
[] mappings
) {
463 return FromMappings(mappings
, (Type
)null);
466 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings1"]/*' />
468 /// <para>[To be supplied.]</para>
470 [PermissionSet(SecurityAction
.LinkDemand
, Name
="FullTrust")]
471 public static XmlSerializer
[] FromMappings(XmlMapping
[] mappings
, Type type
) {
472 if (mappings
== null || mappings
.Length
== 0) return new XmlSerializer
[0];
473 XmlSerializerImplementation contract
= null;
474 Assembly assembly
= type
== null ? null : TempAssembly
.LoadGeneratedAssembly(type
, null, out contract
);
475 TempAssembly tempAssembly
= null;
476 if (assembly
== null) {
477 if (XmlMapping
.IsShallow(mappings
)) {
478 return new XmlSerializer
[0];
482 tempAssembly
= new TempAssembly(mappings
, new Type
[] { type }
, null, null, null);
483 XmlSerializer
[] serializers
= new XmlSerializer
[mappings
.Length
];
485 contract
= tempAssembly
.Contract
;
487 for (int i
= 0; i
< serializers
.Length
; i
++) {
488 serializers
[i
] = (XmlSerializer
)contract
.TypedSerializers
[mappings
[i
].Key
];
489 serializers
[i
].SetTempAssembly(tempAssembly
, mappings
[i
]);
495 // Use XmlSerializer cache when the type is not null.
496 return GetSerializersFromCache(mappings
, type
);
501 XmlSerializer
[] serializers
= new XmlSerializer
[mappings
.Length
];
502 for (int i
= 0; i
< serializers
.Length
; i
++)
503 serializers
[i
] = (XmlSerializer
)contract
.TypedSerializers
[mappings
[i
].Key
];
508 static XmlSerializer
[] GetSerializersFromCache(XmlMapping
[] mappings
, Type type
) {
509 XmlSerializer
[] serializers
= new XmlSerializer
[mappings
.Length
];
511 Hashtable typedMappingTable
= null;
512 lock (xmlSerializerTable
) {
513 typedMappingTable
= xmlSerializerTable
[type
] as Hashtable
;
514 if (typedMappingTable
== null) {
515 typedMappingTable
= new Hashtable();
516 xmlSerializerTable
[type
] = typedMappingTable
;
520 lock (typedMappingTable
) {
521 Hashtable pendingKeys
= new Hashtable();
522 for (int i
= 0; i
< mappings
.Length
; i
++) {
523 XmlSerializerMappingKey mappingKey
= new XmlSerializerMappingKey(mappings
[i
]);
524 serializers
[i
] = typedMappingTable
[mappingKey
] as XmlSerializer
;
525 if (serializers
[i
] == null) {
526 pendingKeys
.Add(mappingKey
, i
);
530 if (pendingKeys
.Count
> 0) {
531 XmlMapping
[] pendingMappings
= new XmlMapping
[pendingKeys
.Count
];
533 foreach (XmlSerializerMappingKey mappingKey
in pendingKeys
.Keys
) {
534 pendingMappings
[index
++] = mappingKey
.Mapping
;
537 TempAssembly tempAssembly
= new TempAssembly(pendingMappings
, new Type
[] { type }
, null, null, null);
538 XmlSerializerImplementation contract
= tempAssembly
.Contract
;
540 foreach (XmlSerializerMappingKey mappingKey
in pendingKeys
.Keys
) {
541 index
= (int)pendingKeys
[mappingKey
];
542 serializers
[index
] = (XmlSerializer
)contract
.TypedSerializers
[mappingKey
.Mapping
.Key
];
543 serializers
[index
].SetTempAssembly(tempAssembly
, mappingKey
.Mapping
);
545 typedMappingTable
[mappingKey
] = serializers
[index
];
553 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromMappings3"]/*' />
555 /// <para>[To be supplied.]</para>
557 [PermissionSet(SecurityAction
.LinkDemand
, Name
="FullTrust")]
558 [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of FromMappings which does not take an Evidence parameter. See http://go2.microsoft.com/fwlink/?LinkId=131738 for more information.")]
559 public static XmlSerializer
[] FromMappings(XmlMapping
[] mappings
, Evidence evidence
) {
560 if (mappings
== null || mappings
.Length
== 0) return new XmlSerializer
[0];
561 if (XmlMapping
.IsShallow(mappings
)) {
562 return new XmlSerializer
[0];
564 TempAssembly tempAssembly
= new TempAssembly(mappings
, new Type
[0], null, null, evidence
);
565 XmlSerializerImplementation contract
= tempAssembly
.Contract
;
566 XmlSerializer
[] serializers
= new XmlSerializer
[mappings
.Length
];
567 for (int i
= 0; i
< serializers
.Length
; i
++) {
568 serializers
[i
] = (XmlSerializer
)contract
.TypedSerializers
[mappings
[i
].Key
];
573 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GenerateSerializer"]/*' />
575 /// <para>[To be supplied.]</para>
577 [PermissionSet(SecurityAction
.LinkDemand
, Name
="FullTrust")]
578 public static Assembly
GenerateSerializer(Type
[] types
, XmlMapping
[] mappings
) {
579 CompilerParameters parameters
= new CompilerParameters();
580 parameters
.TempFiles
= new TempFileCollection();
581 parameters
.GenerateInMemory
= false;
582 parameters
.IncludeDebugInformation
= false;
583 return GenerateSerializer(types
, mappings
, parameters
);
586 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GenerateSerializer1"]/*' />
588 /// <para>[To be supplied.]</para>
590 // SxS: This method does not take any resource name and does not expose any resources to the caller.
591 // It's OK to suppress the SxS warning.
592 [PermissionSet(SecurityAction
.Demand
, Name
="FullTrust")]
593 [ResourceConsumption(ResourceScope
.Machine
, ResourceScope
.Machine
)]
594 [ResourceExposure(ResourceScope
.None
)]
595 public static Assembly
GenerateSerializer(Type
[] types
, XmlMapping
[] mappings
, CompilerParameters parameters
) {
596 if (types
== null || types
.Length
== 0)
599 if (mappings
== null)
600 throw new ArgumentNullException("mappings");
602 if (XmlMapping
.IsShallow(mappings
)) {
603 throw new InvalidOperationException(Res
.GetString(Res
.XmlMelformMapping
));
606 Assembly assembly
= null;
607 for (int i
= 0; i
< types
.Length
; i
++) {
608 Type type
= types
[i
];
609 if (DynamicAssemblies
.IsTypeDynamic(type
)) {
610 throw new InvalidOperationException(Res
.GetString(Res
.XmlPregenTypeDynamic
, type
.FullName
));
612 if (assembly
== null)
613 assembly
= type
.Assembly
;
614 else if (type
.Assembly
!= assembly
) {
615 throw new ArgumentException(Res
.GetString(Res
.XmlPregenOrphanType
, type
.FullName
, assembly
.Location
), "types");
618 return TempAssembly
.GenerateAssembly(mappings
, types
, null, null, XmlSerializerCompilerParameters
.Create(parameters
, /* needTempDirAccess = */ true), assembly
, new Hashtable());
621 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.FromTypes"]/*' />
623 /// <para>[To be supplied.]</para>
625 public static XmlSerializer
[] FromTypes(Type
[] types
) {
627 return new XmlSerializer
[0];
628 XmlReflectionImporter importer
= new XmlReflectionImporter();
629 XmlTypeMapping
[] mappings
= new XmlTypeMapping
[types
.Length
];
630 for (int i
= 0; i
< types
.Length
; i
++) {
631 mappings
[i
] = importer
.ImportTypeMapping(types
[i
]);
633 return FromMappings(mappings
);
637 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GetXmlSerializerAssemblyName"]/*' />
639 /// <para>[To be supplied.]</para>
641 [PermissionSet(SecurityAction
.Demand
, Name
="FullTrust")]
642 public static string GetXmlSerializerAssemblyName(Type type
) {
643 return GetXmlSerializerAssemblyName(type
, null);
646 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.GetXmlSerializerAssemblyName"]/*' />
648 /// <para>[To be supplied.]</para>
650 [PermissionSet(SecurityAction
.Demand
, Name
="FullTrust")]
651 public static string GetXmlSerializerAssemblyName(Type type
, string defaultNamespace
) {
653 throw new ArgumentNullException("type");
655 return Compiler
.GetTempAssemblyName(type
.Assembly
.GetName(), defaultNamespace
);
658 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownNode"]/*' />
660 /// <para>[To be supplied.]</para>
662 public event XmlNodeEventHandler UnknownNode
{
664 events
.OnUnknownNode
+= value;
667 events
.OnUnknownNode
-= value;
671 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownAttribute"]/*' />
673 /// <para>[To be supplied.]</para>
675 public event XmlAttributeEventHandler UnknownAttribute
{
677 events
.OnUnknownAttribute
+= value;
680 events
.OnUnknownAttribute
-= value;
684 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnknownElement"]/*' />
685 public event XmlElementEventHandler UnknownElement
{
687 events
.OnUnknownElement
+= value;
690 events
.OnUnknownElement
-= value;
694 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.UnreferencedObject"]/*' />
695 public event UnreferencedObjectEventHandler UnreferencedObject
{
697 events
.OnUnreferencedObject
+= value;
700 events
.OnUnreferencedObject
-= value;
704 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CreateReader"]/*' />
706 protected virtual XmlSerializationReader
CreateReader() {throw new NotImplementedException();}
707 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Deserialize4"]/*' />
709 protected virtual object Deserialize(XmlSerializationReader reader
){throw new NotImplementedException();}
710 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.CreateWriter"]/*' />
712 protected virtual XmlSerializationWriter
CreateWriter(){throw new NotImplementedException();}
713 /// <include file='doc\XmlSerializer.uex' path='docs/doc[@for="XmlSerializer.Serialize7"]/*' />
715 protected virtual void Serialize(object o
, XmlSerializationWriter writer
){throw new NotImplementedException();}
717 internal void SetTempAssembly(TempAssembly tempAssembly
, XmlMapping mapping
) {
718 this.tempAssembly
= tempAssembly
;
719 this.mapping
= mapping
;
720 this.typedSerializer
= true;
723 static XmlTypeMapping
GetKnownMapping(Type type
, string ns
) {
724 if (ns
!= null && ns
!= string.Empty
)
726 TypeDesc typeDesc
= (TypeDesc
)TypeScope
.PrimtiveTypes
[type
];
727 if (typeDesc
== null)
729 ElementAccessor element
= new ElementAccessor();
730 element
.Name
= typeDesc
.DataType
.Name
;
731 XmlTypeMapping mapping
= new XmlTypeMapping(null, element
);
732 mapping
.SetKeyInternal(XmlMapping
.GenerateKey(type
, null, null));
736 void SerializePrimitive(XmlWriter xmlWriter
, object o
, XmlSerializerNamespaces namespaces
) {
737 XmlSerializationPrimitiveWriter writer
= new XmlSerializationPrimitiveWriter();
738 writer
.Init(xmlWriter
, namespaces
, null, null, null);
739 switch (Type
.GetTypeCode(primitiveType
)) {
740 case TypeCode
.String
:
741 writer
.Write_string(o
);
746 case TypeCode
.Boolean
:
747 writer
.Write_boolean(o
);
750 writer
.Write_short(o
);
753 writer
.Write_long(o
);
755 case TypeCode
.Single
:
756 writer
.Write_float(o
);
758 case TypeCode
.Double
:
759 writer
.Write_double(o
);
761 case TypeCode
.Decimal
:
762 writer
.Write_decimal(o
);
764 case TypeCode
.DateTime
:
765 writer
.Write_dateTime(o
);
768 writer
.Write_char(o
);
771 writer
.Write_unsignedByte(o
);
774 writer
.Write_byte(o
);
776 case TypeCode
.UInt16
:
777 writer
.Write_unsignedShort(o
);
779 case TypeCode
.UInt32
:
780 writer
.Write_unsignedInt(o
);
782 case TypeCode
.UInt64
:
783 writer
.Write_unsignedLong(o
);
787 if (primitiveType
== typeof(XmlQualifiedName
)) {
788 writer
.Write_QName(o
);
790 else if (primitiveType
== typeof(byte[])) {
791 writer
.Write_base64Binary(o
);
793 else if (primitiveType
== typeof(Guid
)) {
794 writer
.Write_guid(o
);
796 else if (primitiveType
== typeof(TimeSpan
)) {
797 writer
.Write_TimeSpan(o
);
800 throw new InvalidOperationException(Res
.GetString(Res
.XmlUnxpectedType
, primitiveType
.FullName
));
806 object DeserializePrimitive(XmlReader xmlReader
, XmlDeserializationEvents events
) {
807 XmlSerializationPrimitiveReader reader
= new XmlSerializationPrimitiveReader();
808 reader
.Init(xmlReader
, events
, null, null);
810 switch (Type
.GetTypeCode(primitiveType
)) {
811 case TypeCode
.String
:
812 o
= reader
.Read_string();
815 o
= reader
.Read_int();
817 case TypeCode
.Boolean
:
818 o
= reader
.Read_boolean();
821 o
= reader
.Read_short();
824 o
= reader
.Read_long();
826 case TypeCode
.Single
:
827 o
= reader
.Read_float();
829 case TypeCode
.Double
:
830 o
= reader
.Read_double();
832 case TypeCode
.Decimal
:
833 o
= reader
.Read_decimal();
835 case TypeCode
.DateTime
:
836 o
= reader
.Read_dateTime();
839 o
= reader
.Read_char();
842 o
= reader
.Read_unsignedByte();
845 o
= reader
.Read_byte();
847 case TypeCode
.UInt16
:
848 o
= reader
.Read_unsignedShort();
850 case TypeCode
.UInt32
:
851 o
= reader
.Read_unsignedInt();
853 case TypeCode
.UInt64
:
854 o
= reader
.Read_unsignedLong();
858 if (primitiveType
== typeof(XmlQualifiedName
)) {
859 o
= reader
.Read_QName();
861 else if (primitiveType
== typeof(byte[])) {
862 o
= reader
.Read_base64Binary();
864 else if (primitiveType
== typeof(Guid
)) {
865 o
= reader
.Read_guid();
867 else if (primitiveType
== typeof(TimeSpan
) && LocalAppContextSwitches
.EnableTimeSpanSerialization
) {
868 o
= reader
.Read_TimeSpan();
871 throw new InvalidOperationException(Res
.GetString(Res
.XmlUnxpectedType
, primitiveType
.FullName
));
878 class XmlSerializerMappingKey
{
879 public XmlMapping Mapping
;
880 public XmlSerializerMappingKey(XmlMapping mapping
) {
881 this.Mapping
= mapping
;
884 public override bool Equals(object obj
) {
885 XmlSerializerMappingKey other
= obj
as XmlSerializerMappingKey
;
889 if (this.Mapping
.Key
!= other
.Mapping
.Key
)
892 if (this.Mapping
.ElementName
!= other
.Mapping
.ElementName
)
895 if (this.Mapping
.Namespace
!= other
.Mapping
.Namespace
)
898 if (this.Mapping
.IsSoap
!= other
.Mapping
.IsSoap
)
904 public override int GetHashCode() {
905 int hashCode
= this.Mapping
.IsSoap
? 0 : 1;
907 if (this.Mapping
.Key
!= null)
908 hashCode ^
= this.Mapping
.Key
.GetHashCode();
910 if (this.Mapping
.ElementName
!= null)
911 hashCode ^
= this.Mapping
.ElementName
.GetHashCode();
913 if (this.Mapping
.Namespace
!= null)
914 hashCode ^
= this.Mapping
.Namespace
.GetHashCode();