| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Security;
- using System.Threading;
- using System.Xml;
- using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
- #if USE_REFEMIT
- public sealed class ClassDataContract : DataContract
- #else
- internal sealed class ClassDataContract : DataContract
- #endif
- {
- [Fx.Tag.SecurityNote(Miscellaneous =
- "RequiresReview - XmlDictionaryString(s) representing the XML namespaces for class members."
- + "statically cached and used from IL generated code. should ideally be Critical."
- + "marked SecurityNode to be callable from transparent IL generated code."
- + "not changed to property to avoid regressing performance; any changes to initalization should be reviewed.")]
- public XmlDictionaryString[] ContractNamespaces;
- [Fx.Tag.SecurityNote(Miscellaneous =
- "RequiresReview - XmlDictionaryString(s) representing the XML element names for class members."
- + "statically cached and used from IL generated code. should ideally be Critical."
- + "marked SecurityNode to be callable from transparent IL generated code."
- + "not changed to property to avoid regressing performance; any changes to initalization should be reviewed.")]
- public XmlDictionaryString[] MemberNames;
- [Fx.Tag.SecurityNote(Miscellaneous =
- "RequiresReview - XmlDictionaryString(s) representing the XML namespaces for class members."
- + "statically cached and used from IL generated code. should ideally be Critical."
- + "marked SecurityNode to be callable from transparent IL generated code."
- + "not changed to property to avoid regressing performance; any changes to initalization should be reviewed.")]
- public XmlDictionaryString[] MemberNamespaces;
- [Fx.Tag.SecurityNote(Critical = "XmlDictionaryString representing the XML namespaces for members of class."
- + "Statically cached and used from IL generated code.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecurityCritical]
- #endif
- XmlDictionaryString[] childElementNamespaces;
- [Fx.Tag.SecurityNote(Critical = "Holds instance of CriticalHelper which keeps state that is cached statically for serialization. "
- + "Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecurityCritical]
- #endif
- ClassDataContractCriticalHelper helper;
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- internal ClassDataContract()
- : base(new ClassDataContractCriticalHelper())
- {
- InitClassDataContract();
- }
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'",
- Safe = "Doesn't leak anything.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecuritySafeCritical]
- #endif
- internal ClassDataContract(Type type)
- : base(new ClassDataContractCriticalHelper(type))
- {
- InitClassDataContract();
- }
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'",
- Safe = "Doesn't leak anything.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecuritySafeCritical]
- #endif
- ClassDataContract(Type type, XmlDictionaryString ns, string[] memberNames)
- : base(new ClassDataContractCriticalHelper(type, ns, memberNames))
- {
- InitClassDataContract();
- }
- [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical fields; called from all constructors.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecurityCritical]
- #endif
- void InitClassDataContract()
- {
- this.helper = base.Helper as ClassDataContractCriticalHelper;
- this.ContractNamespaces = helper.ContractNamespaces;
- this.MemberNames = helper.MemberNames;
- this.MemberNamespaces = helper.MemberNamespaces;
- }
- internal ClassDataContract BaseContract
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical baseContract property.",
- Safe = "baseContract only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.BaseContract; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical baseContract property.")]
- [SecurityCritical]
- set { helper.BaseContract = value; }
- }
- internal List<DataMember> Members
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical members property.",
- Safe = "members only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.Members; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical members property.",
- Safe = "Protected for write if contract has underlyingType.")]
- [SecurityCritical]
- set { helper.Members = value; }
- }
- public XmlDictionaryString[] ChildElementNamespaces
- {
- [Fx.Tag.SecurityNote(Critical = "Sets the critical childElementNamespaces property.",
- Safe = "childElementNamespaces only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (this.childElementNamespaces == null)
- {
- lock (this)
- {
- if (this.childElementNamespaces == null)
- {
- if (helper.ChildElementNamespaces == null)
- {
- XmlDictionaryString[] tempChildElementamespaces = CreateChildElementNamespaces();
- Thread.MemoryBarrier();
- helper.ChildElementNamespaces = tempChildElementamespaces;
- }
- this.childElementNamespaces = helper.ChildElementNamespaces;
- }
- }
- }
- return this.childElementNamespaces;
- }
- }
- internal MethodInfo OnSerializing
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical onSerializing property.",
- Safe = "onSerializing only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.OnSerializing; }
- }
- internal MethodInfo OnSerialized
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical onSerialized property.",
- Safe = "onSerialized only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.OnSerialized; }
- }
- internal MethodInfo OnDeserializing
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical onDeserializing property.",
- Safe = "onDeserializing only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.OnDeserializing; }
- }
- internal MethodInfo OnDeserialized
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical onDeserialized property.",
- Safe = "onDeserialized only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.OnDeserialized; }
- }
- internal MethodInfo ExtensionDataSetMethod
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical extensionDataSetMethod property.",
- Safe = "extensionDataSetMethod only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.ExtensionDataSetMethod; }
- }
- internal override DataContractDictionary KnownDataContracts
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical knownDataContracts property.",
- Safe = "knownDataContracts only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.KnownDataContracts; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical knownDataContracts property.",
- Safe = "Protected for write if contract has underlyingType.")]
- [SecurityCritical]
- set { helper.KnownDataContracts = value; }
- }
- internal override bool IsISerializable
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical isISerializable property.",
- Safe = "isISerializable only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.IsISerializable; }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical isISerializable property.",
- Safe = "Protected for write if contract has underlyingType.")]
- [SecurityCritical]
- set { helper.IsISerializable = value; }
- }
- internal bool IsNonAttributedType
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical IsNonAttributedType property.",
- Safe = "IsNonAttributedType only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.IsNonAttributedType; }
- }
- internal bool HasDataContract
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical hasDataContract property.",
- Safe = "hasDataContract only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.HasDataContract; }
- }
- internal bool HasExtensionData
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical hasExtensionData property.",
- Safe = "hasExtensionData only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.HasExtensionData; }
- }
- internal string SerializationExceptionMessage
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical serializationExceptionMessage property.",
- Safe = "serializationExceptionMessage only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.SerializationExceptionMessage; }
- }
- internal string DeserializationExceptionMessage
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical deserializationExceptionMessage property.",
- Safe = "deserializationExceptionMessage only needs to be protected for write.")]
- [SecuritySafeCritical]
- get { return helper.DeserializationExceptionMessage; }
- }
- internal bool IsReadOnlyContract
- {
- get { return this.DeserializationExceptionMessage != null; }
- }
- [Fx.Tag.SecurityNote(Critical = "Fetches information about which constructor should be used to initialize ISerializable types.",
- Safe = "only needs to be protected for write.")]
- [SecuritySafeCritical]
- internal ConstructorInfo GetISerializableConstructor()
- {
- return helper.GetISerializableConstructor();
- }
- [Fx.Tag.SecurityNote(Critical = "Fetches information about which constructor should be used to initialize non-attributed types that are valid for serialization.",
- Safe = "only needs to be protected for write.")]
- [SecuritySafeCritical]
- internal ConstructorInfo GetNonAttributedTypeConstructor()
- {
- return helper.GetNonAttributedTypeConstructor();
- }
- internal XmlFormatClassWriterDelegate XmlFormatWriterDelegate
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical xmlFormatWriterDelegate property.",
- Safe = "xmlFormatWriterDelegate only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (helper.XmlFormatWriterDelegate == null)
- {
- lock (this)
- {
- if (helper.XmlFormatWriterDelegate == null)
- {
- XmlFormatClassWriterDelegate tempDelegate = new XmlFormatWriterGenerator().GenerateClassWriter(this);
- Thread.MemoryBarrier();
- helper.XmlFormatWriterDelegate = tempDelegate;
- }
- }
- }
- return helper.XmlFormatWriterDelegate;
- }
- }
- internal XmlFormatClassReaderDelegate XmlFormatReaderDelegate
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical xmlFormatReaderDelegate property.",
- Safe = "xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (helper.XmlFormatReaderDelegate == null)
- {
- lock (this)
- {
- if (helper.XmlFormatReaderDelegate == null)
- {
- if (this.IsReadOnlyContract)
- {
- ThrowInvalidDataContractException(helper.DeserializationExceptionMessage, null /*type*/);
- }
- XmlFormatClassReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateClassReader(this);
- Thread.MemoryBarrier();
- helper.XmlFormatReaderDelegate = tempDelegate;
- }
- }
- }
- return helper.XmlFormatReaderDelegate;
- }
- }
- internal static ClassDataContract CreateClassDataContractForKeyValue(Type type, XmlDictionaryString ns, string[] memberNames)
- {
- return new ClassDataContract(type, ns, memberNames);
- }
- internal static void CheckAndAddMember(List<DataMember> members, DataMember memberContract, Dictionary<string, DataMember> memberNamesTable)
- {
- DataMember existingMemberContract;
- if (memberNamesTable.TryGetValue(memberContract.Name, out existingMemberContract))
- {
- Type declaringType = memberContract.MemberInfo.DeclaringType;
- DataContract.ThrowInvalidDataContractException(
- SR.GetString((declaringType.IsEnum ? SR.DupEnumMemberValue : SR.DupMemberName),
- existingMemberContract.MemberInfo.Name,
- memberContract.MemberInfo.Name,
- DataContract.GetClrTypeFullName(declaringType),
- memberContract.Name),
- declaringType);
- }
- memberNamesTable.Add(memberContract.Name, memberContract);
- members.Add(memberContract);
- }
- internal static XmlDictionaryString GetChildNamespaceToDeclare(DataContract dataContract, Type childType, XmlDictionary dictionary)
- {
- childType = DataContract.UnwrapNullableType(childType);
- if (!childType.IsEnum && !Globals.TypeOfIXmlSerializable.IsAssignableFrom(childType)
- && DataContract.GetBuiltInDataContract(childType) == null && childType != Globals.TypeOfDBNull)
- {
- string ns = DataContract.GetStableName(childType).Namespace;
- if (ns.Length > 0 && ns != dataContract.Namespace.Value)
- return dictionary.Add(ns);
- }
- return null;
- }
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - callers may need to depend on isNonAttributedType for a security decision."
- + "isNonAttributedType must be calculated correctly."
- + "IsNonAttributedTypeValidForSerialization is used as part of the isNonAttributedType calculation and is therefore marked with SecurityNote.",
- Safe = "Does not let caller influence isNonAttributedType calculation; no harm in leaking value.")]
- // check whether a corresponding update is required in DataContractCriticalHelper.CreateDataContract
- static internal bool IsNonAttributedTypeValidForSerialization(Type type)
- {
- if (type.IsArray)
- return false;
- if (type.IsEnum)
- return false;
- if (type.IsGenericParameter)
- return false;
- if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type))
- return false;
- if (type.IsPointer)
- return false;
- if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
- return false;
- Type[] interfaceTypes = type.GetInterfaces();
- foreach (Type interfaceType in interfaceTypes)
- {
- if (CollectionDataContract.IsCollectionInterface(interfaceType))
- return false;
- }
- if (type.IsSerializable)
- return false;
- if (Globals.TypeOfISerializable.IsAssignableFrom(type))
- return false;
- if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
- return false;
- if (type == Globals.TypeOfExtensionDataObject)
- return false;
- if (type.IsValueType)
- {
- return type.IsVisible;
- }
- else
- {
- return (type.IsVisible &&
- type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null) != null);
- }
- }
- XmlDictionaryString[] CreateChildElementNamespaces()
- {
- if (Members == null)
- return null;
- XmlDictionaryString[] baseChildElementNamespaces = null;
- if (this.BaseContract != null)
- baseChildElementNamespaces = this.BaseContract.ChildElementNamespaces;
- int baseChildElementNamespaceCount = (baseChildElementNamespaces != null) ? baseChildElementNamespaces.Length : 0;
- XmlDictionaryString[] childElementNamespaces = new XmlDictionaryString[Members.Count + baseChildElementNamespaceCount];
- if (baseChildElementNamespaceCount > 0)
- Array.Copy(baseChildElementNamespaces, 0, childElementNamespaces, 0, baseChildElementNamespaces.Length);
- XmlDictionary dictionary = new XmlDictionary();
- for (int i = 0; i < this.Members.Count; i++)
- {
- childElementNamespaces[i + baseChildElementNamespaceCount] = GetChildNamespaceToDeclare(this, this.Members[i].MemberType, dictionary);
- }
- return childElementNamespaces;
- }
- [Fx.Tag.SecurityNote(Critical = "Calls critical method on helper.",
- Safe = "Doesn't leak anything.")]
- [SecuritySafeCritical]
- void EnsureMethodsImported()
- {
- helper.EnsureMethodsImported();
- }
- public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
- {
- XmlFormatWriterDelegate(xmlWriter, obj, context, this);
- }
- public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
- {
- xmlReader.Read();
- object o = XmlFormatReaderDelegate(xmlReader, context, MemberNames, MemberNamespaces);
- xmlReader.ReadEndElement();
- return o;
- }
- #if !NO_DYNAMIC_CODEGEN
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - calculates whether this class requires MemberAccessPermission for deserialization."
- + "Since this information is used to determine whether to give the generated code access "
- + "permissions to private members, any changes to the logic should be reviewed.")]
- internal bool RequiresMemberAccessForRead(SecurityException securityException)
- {
- EnsureMethodsImported();
- if (!IsTypeVisible(UnderlyingType))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractTypeNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- if (this.BaseContract != null && this.BaseContract.RequiresMemberAccessForRead(securityException))
- return true;
- if (ConstructorRequiresMemberAccess(GetISerializableConstructor()))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustISerializableNoPublicConstructor,
- DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- if (ConstructorRequiresMemberAccess(GetNonAttributedTypeConstructor()))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustNonAttributedSerializableTypeNoPublicConstructor,
- DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- if (MethodRequiresMemberAccess(this.OnDeserializing))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractOnDeserializingNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.OnDeserializing.Name),
- securityException));
- }
- return true;
- }
- if (MethodRequiresMemberAccess(this.OnDeserialized))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractOnDeserializedNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.OnDeserialized.Name),
- securityException));
- }
- return true;
- }
- if (this.Members != null)
- {
- for (int i = 0; i < this.Members.Count; i++)
- {
- if (this.Members[i].RequiresMemberAccessForSet())
- {
- if (securityException != null)
- {
- if (this.Members[i].MemberInfo is FieldInfo)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractFieldSetNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.Members[i].MemberInfo.Name),
- securityException));
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractPropertySetNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.Members[i].MemberInfo.Name),
- securityException));
- }
- }
- return true;
- }
- }
- }
- return false;
- }
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - calculates whether this class requires MemberAccessPermission for serialization."
- + " Since this information is used to determine whether to give the generated code access"
- + " permissions to private members, any changes to the logic should be reviewed.")]
- internal bool RequiresMemberAccessForWrite(SecurityException securityException)
- {
- #if FEATURE_MONO_CAS
- EnsureMethodsImported();
- if (!IsTypeVisible(UnderlyingType))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractTypeNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType)),
- securityException));
- }
- return true;
- }
- if (this.BaseContract != null && this.BaseContract.RequiresMemberAccessForWrite(securityException))
- return true;
- if (MethodRequiresMemberAccess(this.OnSerializing))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractOnSerializingNotPublic,
- DataContract.GetClrTypeFullName(this.UnderlyingType),
- this.OnSerializing.Name),
- securityException));
- }
- return true;
- }
- if (MethodRequiresMemberAccess(this.OnSerialized))
- {
- if (securityException != null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractOnSerializedNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.OnSerialized.Name),
- securityException));
- }
- return true;
- }
- if (this.Members != null)
- {
- for (int i = 0; i < this.Members.Count; i++)
- {
- if (this.Members[i].RequiresMemberAccessForGet())
- {
- if (securityException != null)
- {
- if (this.Members[i].MemberInfo is FieldInfo)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractFieldGetNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.Members[i].MemberInfo.Name),
- securityException));
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new SecurityException(SR.GetString(
- SR.PartialTrustDataContractPropertyGetNotPublic,
- DataContract.GetClrTypeFullName(UnderlyingType),
- this.Members[i].MemberInfo.Name),
- securityException));
- }
- }
- return true;
- }
- }
- }
- return false;
- #else
- return true;
- #endif
- }
- #endif
- [Fx.Tag.SecurityNote(Critical = "Holds all state used for (de)serializing classes."
- + " Since the data is cached statically, we lock down access to it.")]
- #if !NO_SECURITY_ATTRIBUTES
- [SecurityCritical(SecurityCriticalScope.Everything)]
- #endif
- class ClassDataContractCriticalHelper : DataContract.DataContractCriticalHelper
- {
- ClassDataContract baseContract;
- List<DataMember> members;
- MethodInfo onSerializing, onSerialized;
- MethodInfo onDeserializing, onDeserialized;
- MethodInfo extensionDataSetMethod;
- DataContractDictionary knownDataContracts;
- string serializationExceptionMessage;
- bool isISerializable;
- bool isKnownTypeAttributeChecked;
- bool isMethodChecked;
- bool hasExtensionData;
- [Fx.Tag.SecurityNote(Miscellaneous = "in serialization/deserialization we base the decision whether to Demand SerializationFormatter permission on this value and hasDataContract.")]
- bool isNonAttributedType;
- [Fx.Tag.SecurityNote(Miscellaneous = "in serialization/deserialization we base the decision whether to Demand SerializationFormatter permission on this value and isNonAttributedType.")]
- bool hasDataContract;
- XmlDictionaryString[] childElementNamespaces;
- XmlFormatClassReaderDelegate xmlFormatReaderDelegate;
- XmlFormatClassWriterDelegate xmlFormatWriterDelegate;
- public XmlDictionaryString[] ContractNamespaces;
- public XmlDictionaryString[] MemberNames;
- public XmlDictionaryString[] MemberNamespaces;
- internal ClassDataContractCriticalHelper()
- : base()
- {
- }
- internal ClassDataContractCriticalHelper(Type type)
- : base(type)
- {
- XmlQualifiedName stableName = GetStableNameAndSetHasDataContract(type);
- if (type == Globals.TypeOfDBNull)
- {
- this.StableName = stableName;
- this.members = new List<DataMember>();
- XmlDictionary dictionary = new XmlDictionary(2);
- this.Name = dictionary.Add(StableName.Name);
- this.Namespace = dictionary.Add(StableName.Namespace);
- this.ContractNamespaces = this.MemberNames = this.MemberNamespaces = new XmlDictionaryString[] { };
- EnsureMethodsImported();
- return;
- }
- Type baseType = type.BaseType;
- this.isISerializable = (Globals.TypeOfISerializable.IsAssignableFrom(type));
- SetIsNonAttributedType(type);
- if (this.isISerializable)
- {
- if (HasDataContract)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.ISerializableCannotHaveDataContract, DataContract.GetClrTypeFullName(type))));
- if (baseType != null && !(baseType.IsSerializable && Globals.TypeOfISerializable.IsAssignableFrom(baseType)))
- baseType = null;
- }
- this.IsValueType = type.IsValueType;
- if (baseType != null && baseType != Globals.TypeOfObject && baseType != Globals.TypeOfValueType && baseType != Globals.TypeOfUri)
- {
- DataContract baseContract = DataContract.GetDataContract(baseType);
- if (baseContract is CollectionDataContract)
- this.BaseContract = ((CollectionDataContract)baseContract).SharedTypeContract as ClassDataContract;
- else
- this.BaseContract = baseContract as ClassDataContract;
- if (this.BaseContract != null && this.BaseContract.IsNonAttributedType && !this.isNonAttributedType)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError
- (new InvalidDataContractException(SR.GetString(SR.AttributedTypesCannotInheritFromNonAttributedSerializableTypes,
- DataContract.GetClrTypeFullName(type), DataContract.GetClrTypeFullName(baseType))));
- }
- }
- else
- this.BaseContract = null;
- hasExtensionData = (Globals.TypeOfIExtensibleDataObject.IsAssignableFrom(type));
- if (hasExtensionData && !HasDataContract && !IsNonAttributedType)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.OnlyDataContractTypesCanHaveExtensionData, DataContract.GetClrTypeFullName(type))));
- if (this.isISerializable)
- SetDataContractName(stableName);
- else
- {
- this.StableName = stableName;
- ImportDataMembers();
- XmlDictionary dictionary = new XmlDictionary(2 + Members.Count);
- Name = dictionary.Add(StableName.Name);
- Namespace = dictionary.Add(StableName.Namespace);
- int baseMemberCount = 0;
- int baseContractCount = 0;
- if (BaseContract == null)
- {
- MemberNames = new XmlDictionaryString[Members.Count];
- MemberNamespaces = new XmlDictionaryString[Members.Count];
- ContractNamespaces = new XmlDictionaryString[1];
- }
- else
- {
- if (BaseContract.IsReadOnlyContract)
- {
- this.serializationExceptionMessage = BaseContract.SerializationExceptionMessage;
- }
- baseMemberCount = BaseContract.MemberNames.Length;
- MemberNames = new XmlDictionaryString[Members.Count + baseMemberCount];
- Array.Copy(BaseContract.MemberNames, MemberNames, baseMemberCount);
- MemberNamespaces = new XmlDictionaryString[Members.Count + baseMemberCount];
- Array.Copy(BaseContract.MemberNamespaces, MemberNamespaces, baseMemberCount);
- baseContractCount = BaseContract.ContractNamespaces.Length;
- ContractNamespaces = new XmlDictionaryString[1 + baseContractCount];
- Array.Copy(BaseContract.ContractNamespaces, ContractNamespaces, baseContractCount);
- }
- ContractNamespaces[baseContractCount] = Namespace;
- for (int i = 0; i < Members.Count; i++)
- {
- MemberNames[i + baseMemberCount] = dictionary.Add(Members[i].Name);
- MemberNamespaces[i + baseMemberCount] = Namespace;
- }
- }
- EnsureMethodsImported();
- }
- internal ClassDataContractCriticalHelper(Type type, XmlDictionaryString ns, string[] memberNames)
- : base(type)
- {
- this.StableName = new XmlQualifiedName(GetStableNameAndSetHasDataContract(type).Name, ns.Value);
- ImportDataMembers();
- XmlDictionary dictionary = new XmlDictionary(1 + Members.Count);
- Name = dictionary.Add(StableName.Name);
- Namespace = ns;
- ContractNamespaces = new XmlDictionaryString[] { Namespace };
- MemberNames = new XmlDictionaryString[Members.Count];
- MemberNamespaces = new XmlDictionaryString[Members.Count];
- for (int i = 0; i < Members.Count; i++)
- {
- Members[i].Name = memberNames[i];
- MemberNames[i] = dictionary.Add(Members[i].Name);
- MemberNamespaces[i] = Namespace;
- }
- EnsureMethodsImported();
- }
- void EnsureIsReferenceImported(Type type)
- {
- DataContractAttribute dataContractAttribute;
- bool isReference = false;
- bool hasDataContractAttribute = TryGetDCAttribute(type, out dataContractAttribute);
- if (BaseContract != null)
- {
- if (hasDataContractAttribute && dataContractAttribute.IsReferenceSetExplicitly)
- {
- bool baseIsReference = this.BaseContract.IsReference;
- if ((baseIsReference && !dataContractAttribute.IsReference) ||
- (!baseIsReference && dataContractAttribute.IsReference))
- {
- DataContract.ThrowInvalidDataContractException(
- SR.GetString(SR.InconsistentIsReference,
- DataContract.GetClrTypeFullName(type),
- dataContractAttribute.IsReference,
- DataContract.GetClrTypeFullName(this.BaseContract.UnderlyingType),
- this.BaseContract.IsReference),
- type);
- }
- else
- {
- isReference = dataContractAttribute.IsReference;
- }
- }
- else
- {
- isReference = this.BaseContract.IsReference;
- }
- }
- else if (hasDataContractAttribute)
- {
- if (dataContractAttribute.IsReference)
- isReference = dataContractAttribute.IsReference;
- }
- if (isReference && type.IsValueType)
- {
- DataContract.ThrowInvalidDataContractException(
- SR.GetString(SR.ValueTypeCannotHaveIsReference,
- DataContract.GetClrTypeFullName(type),
- true,
- false),
- type);
- return;
- }
- this.IsReference = isReference;
- }
- void ImportDataMembers()
- {
- Type type = this.UnderlyingType;
- EnsureIsReferenceImported(type);
- List<DataMember> tempMembers = new List<DataMember>();
- Dictionary<string, DataMember> memberNamesTable = new Dictionary<string, DataMember>();
- MemberInfo[] memberInfos;
- if (this.isNonAttributedType)
- {
- memberInfos = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
- }
- else
- {
- memberInfos = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- }
- for (int i = 0; i < memberInfos.Length; i++)
- {
- MemberInfo member = memberInfos[i];
- if (HasDataContract)
- {
- object[] memberAttributes = member.GetCustomAttributes(typeof(DataMemberAttribute), false);
- if (memberAttributes != null && memberAttributes.Length > 0)
- {
- if (memberAttributes.Length > 1)
- ThrowInvalidDataContractException(SR.GetString(SR.TooManyDataMembers, DataContract.GetClrTypeFullName(member.DeclaringType), member.Name));
- DataMember memberContract = new DataMember(member);
- if (member.MemberType == MemberTypes.Property)
- {
- PropertyInfo property = (PropertyInfo)member;
- MethodInfo getMethod = property.GetGetMethod(true);
- if (getMethod != null && IsMethodOverriding(getMethod))
- continue;
- MethodInfo setMethod = property.GetSetMethod(true);
- if (setMethod != null && IsMethodOverriding(setMethod))
- continue;
- if (getMethod == null)
- ThrowInvalidDataContractException(SR.GetString(SR.NoGetMethodForProperty, property.DeclaringType, property.Name));
- if (setMethod == null)
- {
- if (!SetIfGetOnlyCollection(memberContract, skipIfReadOnlyContract: false))
- {
- this.serializationExceptionMessage = SR.GetString(SR.NoSetMethodForProperty, property.DeclaringType, property.Name);
- }
- }
- if (getMethod.GetParameters().Length > 0)
- ThrowInvalidDataContractException(SR.GetString(SR.IndexedPropertyCannotBeSerialized, property.DeclaringType, property.Name));
- }
- else if (member.MemberType != MemberTypes.Field)
- ThrowInvalidDataContractException(SR.GetString(SR.InvalidMember, DataContract.GetClrTypeFullName(type), member.Name));
- DataMemberAttribute memberAttribute = (DataMemberAttribute)memberAttributes[0];
- if (memberAttribute.IsNameSetExplicitly)
- {
- if (memberAttribute.Name == null || memberAttribute.Name.Length == 0)
- ThrowInvalidDataContractException(SR.GetString(SR.InvalidDataMemberName, member.Name, DataContract.GetClrTypeFullName(type)));
- memberContract.Name = memberAttribute.Name;
- }
- else
- memberContract.Name = member.Name;
- memberContract.Name = DataContract.EncodeLocalName(memberContract.Name);
- memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType);
- memberContract.IsRequired = memberAttribute.IsRequired;
- if (memberAttribute.IsRequired && this.IsReference)
- {
- ThrowInvalidDataContractException(
- SR.GetString(SR.IsRequiredDataMemberOnIsReferenceDataContractType,
- DataContract.GetClrTypeFullName(member.DeclaringType),
- member.Name, true), type);
- }
- memberContract.EmitDefaultValue = memberAttribute.EmitDefaultValue;
- memberContract.Order = memberAttribute.Order;
- CheckAndAddMember(tempMembers, memberContract, memberNamesTable);
- }
- }
- else if (this.isNonAttributedType)
- {
- FieldInfo field = member as FieldInfo;
- PropertyInfo property = member as PropertyInfo;
- if ((field == null && property == null) || (field != null && field.IsInitOnly))
- continue;
- object[] memberAttributes = member.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), false);
- if (memberAttributes != null && memberAttributes.Length > 0)
- {
- if (memberAttributes.Length > 1)
- ThrowInvalidDataContractException(SR.GetString(SR.TooManyIgnoreDataMemberAttributes, DataContract.GetClrTypeFullName(member.DeclaringType), member.Name));
- else
- continue;
- }
- DataMember memberContract = new DataMember(member);
- if (property != null)
- {
- MethodInfo getMethod = property.GetGetMethod();
- if (getMethod == null || IsMethodOverriding(getMethod) || getMethod.GetParameters().Length > 0)
- continue;
- MethodInfo setMethod = property.GetSetMethod(true);
- if (setMethod == null)
- {
- // if the collection doesn't have the 'Add' method, we will skip it, for compatibility with 4.0
- if (!SetIfGetOnlyCollection(memberContract, skipIfReadOnlyContract: true))
- continue;
- }
- else
- {
- if (!setMethod.IsPublic || IsMethodOverriding(setMethod))
- continue;
- }
- //skip ExtensionData member of type ExtensionDataObject if IExtensibleDataObject is implemented in non-attributed type
- if (this.hasExtensionData && memberContract.MemberType == Globals.TypeOfExtensionDataObject
- && member.Name == Globals.ExtensionDataObjectPropertyName)
- continue;
- }
- memberContract.Name = DataContract.EncodeLocalName(member.Name);
- memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType);
- CheckAndAddMember(tempMembers, memberContract, memberNamesTable);
- }
- else
- {
- FieldInfo field = member as FieldInfo;
- if (field != null && !field.IsNotSerialized)
- {
- DataMember memberContract = new DataMember(member);
- memberContract.Name = DataContract.EncodeLocalName(member.Name);
- object[] optionalFields = field.GetCustomAttributes(Globals.TypeOfOptionalFieldAttribute, false);
- if (optionalFields == null || optionalFields.Length == 0)
- {
- if (this.IsReference)
- {
- ThrowInvalidDataContractException(
- SR.GetString(SR.NonOptionalFieldMemberOnIsReferenceSerializableType,
- DataContract.GetClrTypeFullName(member.DeclaringType),
- member.Name, true), type);
- }
- memberContract.IsRequired = true;
- }
- memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType);
- CheckAndAddMember(tempMembers, memberContract, memberNamesTable);
- }
- }
- }
- if (tempMembers.Count > 1)
- tempMembers.Sort(DataMemberComparer.Singleton);
- SetIfMembersHaveConflict(tempMembers);
- Thread.MemoryBarrier();
- members = tempMembers;
- }
- bool SetIfGetOnlyCollection(DataMember memberContract, bool skipIfReadOnlyContract)
- {
- //OK to call IsCollection here since the use of surrogated collection types is not supported in get-only scenarios
- if (CollectionDataContract.IsCollection(memberContract.MemberType, false /*isConstructorRequired*/, skipIfReadOnlyContract) && !memberContract.MemberType.IsValueType)
- {
- memberContract.IsGetOnlyCollection = true;
- return true;
- }
- return false;
- }
- void SetIfMembersHaveConflict(List<DataMember> members)
- {
- if (BaseContract == null)
- return;
- int baseTypeIndex = 0;
- List<Member> membersInHierarchy = new List<Member>();
- foreach (DataMember member in members)
- {
- membersInHierarchy.Add(new Member(member, this.StableName.Namespace, baseTypeIndex));
- }
- ClassDataContract currContract = BaseContract;
- while (currContract != null)
- {
- baseTypeIndex++;
- foreach (DataMember member in currContract.Members)
- {
- membersInHierarchy.Add(new Member(member, currContract.StableName.Namespace, baseTypeIndex));
- }
- currContract = currContract.BaseContract;
- }
- IComparer<Member> comparer = DataMemberConflictComparer.Singleton;
- membersInHierarchy.Sort(comparer);
- for (int i = 0; i < membersInHierarchy.Count - 1; i++)
- {
- int startIndex = i;
- int endIndex = i;
- bool hasConflictingType = false;
- while (endIndex < membersInHierarchy.Count - 1
- && String.CompareOrdinal(membersInHierarchy[endIndex].member.Name, membersInHierarchy[endIndex + 1].member.Name) == 0
- && String.CompareOrdinal(membersInHierarchy[endIndex].ns, membersInHierarchy[endIndex + 1].ns) == 0)
- {
- membersInHierarchy[endIndex].member.ConflictingMember = membersInHierarchy[endIndex + 1].member;
- if (!hasConflictingType)
- {
- if (membersInHierarchy[endIndex + 1].member.HasConflictingNameAndType)
- {
- hasConflictingType = true;
- }
- else
- {
- hasConflictingType = (membersInHierarchy[endIndex].member.MemberType != membersInHierarchy[endIndex + 1].member.MemberType);
- }
- }
- endIndex++;
- }
- if (hasConflictingType)
- {
- for (int j = startIndex; j <= endIndex; j++)
- {
- membersInHierarchy[j].member.HasConflictingNameAndType = true;
- }
- }
- i = endIndex + 1;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Sets the critical hasDataContract field.",
- Safe = "Uses a trusted critical API (DataContract.GetStableName) to calculate the value, does not accept the value from the caller.")]
- [SecuritySafeCritical]
- XmlQualifiedName GetStableNameAndSetHasDataContract(Type type)
- {
- return DataContract.GetStableName(type, out this.hasDataContract);
- }
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - callers may need to depend on isNonAttributedType for a security decision."
- + "isNonAttributedType must be calculated correctly."
- + "SetIsNonAttributedType should not be called before GetStableNameAndSetHasDataContract since it is dependent on the correct calculation of hasDataContract.",
- Safe = "Does not let caller influence isNonAttributedType calculation; no harm in leaking value.")]
- void SetIsNonAttributedType(Type type)
- {
- this.isNonAttributedType = !type.IsSerializable && !this.hasDataContract && IsNonAttributedTypeValidForSerialization(type);
- }
- static bool IsMethodOverriding(MethodInfo method)
- {
- return method.IsVirtual && ((method.Attributes & MethodAttributes.NewSlot) == 0);
- }
- internal void EnsureMethodsImported()
- {
- if (!isMethodChecked && UnderlyingType != null)
- {
- lock (this)
- {
- if (!isMethodChecked)
- {
- Type type = this.UnderlyingType;
- MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- for (int i = 0; i < methods.Length; i++)
- {
- MethodInfo method = methods[i];
- Type prevAttributeType = null;
- ParameterInfo[] parameters = method.GetParameters();
- if (HasExtensionData && IsValidExtensionDataSetMethod(method, parameters))
- {
- if (method.Name == Globals.ExtensionDataSetExplicitMethod || !method.IsPublic)
- extensionDataSetMethod = XmlFormatGeneratorStatics.ExtensionDataSetExplicitMethodInfo;
- else
- extensionDataSetMethod = method;
- }
- if (IsValidCallback(method, parameters, Globals.TypeOfOnSerializingAttribute, onSerializing, ref prevAttributeType))
- onSerializing = method;
- if (IsValidCallback(method, parameters, Globals.TypeOfOnSerializedAttribute, onSerialized, ref prevAttributeType))
- onSerialized = method;
- if (IsValidCallback(method, parameters, Globals.TypeOfOnDeserializingAttribute, onDeserializing, ref prevAttributeType))
- onDeserializing = method;
- if (IsValidCallback(method, parameters, Globals.TypeOfOnDeserializedAttribute, onDeserialized, ref prevAttributeType))
- onDeserialized = method;
- }
- Thread.MemoryBarrier();
- isMethodChecked = true;
- }
- }
- }
- }
- bool IsValidExtensionDataSetMethod(MethodInfo method, ParameterInfo[] parameters)
- {
- if (method.Name == Globals.ExtensionDataSetExplicitMethod || method.Name == Globals.ExtensionDataSetMethod)
- {
- if (extensionDataSetMethod != null)
- ThrowInvalidDataContractException(SR.GetString(SR.DuplicateExtensionDataSetMethod, method, extensionDataSetMethod, DataContract.GetClrTypeFullName(method.DeclaringType)));
- if (method.ReturnType != Globals.TypeOfVoid)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.ExtensionDataSetMustReturnVoid, DataContract.GetClrTypeFullName(method.DeclaringType), method), method.DeclaringType);
- if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != Globals.TypeOfExtensionDataObject)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.ExtensionDataSetParameterInvalid, DataContract.GetClrTypeFullName(method.DeclaringType), method, Globals.TypeOfExtensionDataObject), method.DeclaringType);
- return true;
- }
- return false;
- }
- static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType)
- {
- if (method.IsDefined(attributeType, false))
- {
- if (currentCallback != null)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.DuplicateCallback, method, currentCallback, DataContract.GetClrTypeFullName(method.DeclaringType), attributeType), method.DeclaringType);
- else if (prevAttributeType != null)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.DuplicateAttribute, prevAttributeType, attributeType, DataContract.GetClrTypeFullName(method.DeclaringType), method), method.DeclaringType);
- else if (method.IsVirtual)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.CallbacksCannotBeVirtualMethods, method, DataContract.GetClrTypeFullName(method.DeclaringType), attributeType), method.DeclaringType);
- else
- {
- if (method.ReturnType != Globals.TypeOfVoid)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.CallbackMustReturnVoid, DataContract.GetClrTypeFullName(method.DeclaringType), method), method.DeclaringType);
- if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != Globals.TypeOfStreamingContext)
- DataContract.ThrowInvalidDataContractException(SR.GetString(SR.CallbackParameterInvalid, DataContract.GetClrTypeFullName(method.DeclaringType), method, Globals.TypeOfStreamingContext), method.DeclaringType);
- prevAttributeType = attributeType;
- }
- return true;
- }
- return false;
- }
- internal ClassDataContract BaseContract
- {
- get { return baseContract; }
- set
- {
- baseContract = value;
- if (baseContract != null && IsValueType)
- ThrowInvalidDataContractException(SR.GetString(SR.ValueTypeCannotHaveBaseType, StableName.Name, StableName.Namespace, baseContract.StableName.Name, baseContract.StableName.Namespace));
- }
- }
- internal List<DataMember> Members
- {
- get { return members; }
- set { members = value; }
- }
- internal MethodInfo OnSerializing
- {
- get
- {
- EnsureMethodsImported();
- return onSerializing;
- }
- }
- internal MethodInfo OnSerialized
- {
- get
- {
- EnsureMethodsImported();
- return onSerialized;
- }
- }
- internal MethodInfo OnDeserializing
- {
- get
- {
- EnsureMethodsImported();
- return onDeserializing;
- }
- }
- internal MethodInfo OnDeserialized
- {
- get
- {
- EnsureMethodsImported();
- return onDeserialized;
- }
- }
- internal MethodInfo ExtensionDataSetMethod
- {
- get
- {
- EnsureMethodsImported();
- return extensionDataSetMethod;
- }
- }
- internal override DataContractDictionary KnownDataContracts
- {
- get
- {
- if (!isKnownTypeAttributeChecked && UnderlyingType != null)
- {
- lock (this)
- {
- if (!isKnownTypeAttributeChecked)
- {
- knownDataContracts = DataContract.ImportKnownTypeAttributes(this.UnderlyingType);
- Thread.MemoryBarrier();
- isKnownTypeAttributeChecked = true;
- }
- }
- }
- return knownDataContracts;
- }
- set { knownDataContracts = value; }
- }
- internal string SerializationExceptionMessage
- {
- get { return serializationExceptionMessage; }
- }
- internal string DeserializationExceptionMessage
- {
- get
- {
- if (serializationExceptionMessage == null)
- {
- return null;
- }
- else
- {
- return SR.GetString(SR.ReadOnlyClassDeserialization, this.serializationExceptionMessage);
- }
- }
- }
- internal override bool IsISerializable
- {
- get { return isISerializable; }
- set { isISerializable = value; }
- }
- internal bool HasDataContract
- {
- get { return hasDataContract; }
- }
- internal bool HasExtensionData
- {
- get { return hasExtensionData; }
- }
- internal bool IsNonAttributedType
- {
- get { return isNonAttributedType; }
- }
- internal ConstructorInfo GetISerializableConstructor()
- {
- if (!IsISerializable)
- return null;
- ConstructorInfo ctor = UnderlyingType.GetConstructor(Globals.ScanAllMembers, null, SerInfoCtorArgs, null);
- if (ctor == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.SerializationInfo_ConstructorNotFound, DataContract.GetClrTypeFullName(UnderlyingType))));
- return ctor;
- }
- internal ConstructorInfo GetNonAttributedTypeConstructor()
- {
- if (!this.IsNonAttributedType)
- return null;
- Type type = UnderlyingType;
- if (type.IsValueType)
- return null;
- ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
- if (ctor == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.NonAttributedSerializableTypesMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));
- return ctor;
- }
- internal XmlFormatClassWriterDelegate XmlFormatWriterDelegate
- {
- get { return xmlFormatWriterDelegate; }
- set { xmlFormatWriterDelegate = value; }
- }
- internal XmlFormatClassReaderDelegate XmlFormatReaderDelegate
- {
- get { return xmlFormatReaderDelegate; }
- set { xmlFormatReaderDelegate = value; }
- }
- public XmlDictionaryString[] ChildElementNamespaces
- {
- get { return childElementNamespaces; }
- set { childElementNamespaces = value; }
- }
- static Type[] serInfoCtorArgs;
- static Type[] SerInfoCtorArgs
- {
- get
- {
- if (serInfoCtorArgs == null)
- serInfoCtorArgs = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
- return serInfoCtorArgs;
- }
- }
- internal struct Member
- {
- internal Member(DataMember member, string ns, int baseTypeIndex)
- {
- this.member = member;
- this.ns = ns;
- this.baseTypeIndex = baseTypeIndex;
- }
- internal DataMember member;
- internal string ns;
- internal int baseTypeIndex;
- }
- internal class DataMemberConflictComparer : IComparer<Member>
- {
- public int Compare(Member x, Member y)
- {
- int nsCompare = String.CompareOrdinal(x.ns, y.ns);
- if (nsCompare != 0)
- return nsCompare;
- int nameCompare = String.CompareOrdinal(x.member.Name, y.member.Name);
- if (nameCompare != 0)
- return nameCompare;
- return x.baseTypeIndex - y.baseTypeIndex;
- }
- internal static DataMemberConflictComparer Singleton = new DataMemberConflictComparer();
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract .",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- internal override DataContract BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts)
- {
- Type type = UnderlyingType;
- if (!type.IsGenericType || !type.ContainsGenericParameters)
- return this;
- lock (this)
- {
- DataContract boundContract;
- if (boundContracts.TryGetValue(this, out boundContract))
- return boundContract;
- ClassDataContract boundClassContract = new ClassDataContract();
- boundContracts.Add(this, boundClassContract);
- XmlQualifiedName stableName;
- object[] genericParams;
- if (type.IsGenericTypeDefinition)
- {
- stableName = this.StableName;
- genericParams = paramContracts;
- }
- else
- {
- //partial Generic: Construct stable name from its open generic type definition
- stableName = DataContract.GetStableName(type.GetGenericTypeDefinition());
- Type[] paramTypes = type.GetGenericArguments();
- genericParams = new object[paramTypes.Length];
- for (int i = 0; i < paramTypes.Length; i++)
- {
- Type paramType = paramTypes[i];
- if (paramType.IsGenericParameter)
- genericParams[i] = paramContracts[paramType.GenericParameterPosition];
- else
- genericParams[i] = paramType;
- }
- }
- boundClassContract.StableName = CreateQualifiedName(DataContract.ExpandGenericParameters(XmlConvert.DecodeName(stableName.Name), new GenericNameProvider(DataContract.GetClrTypeFullName(this.UnderlyingType), genericParams)), stableName.Namespace);
- if (BaseContract != null)
- boundClassContract.BaseContract = (ClassDataContract)BaseContract.BindGenericParameters(paramContracts, boundContracts);
- boundClassContract.IsISerializable = this.IsISerializable;
- boundClassContract.IsValueType = this.IsValueType;
- boundClassContract.IsReference = this.IsReference;
- if (Members != null)
- {
- boundClassContract.Members = new List<DataMember>(Members.Count);
- foreach (DataMember member in Members)
- boundClassContract.Members.Add(member.BindGenericParameters(paramContracts, boundContracts));
- }
- return boundClassContract;
- }
- }
- internal override bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
- {
- if (IsEqualOrChecked(other, checkedContracts))
- return true;
- if (base.Equals(other, checkedContracts))
- {
- ClassDataContract dataContract = other as ClassDataContract;
- if (dataContract != null)
- {
- if (IsISerializable)
- {
- if (!dataContract.IsISerializable)
- return false;
- }
- else
- {
- if (dataContract.IsISerializable)
- return false;
- if (Members == null)
- {
- if (dataContract.Members != null)
- {
- // check that all the datamembers in dataContract.Members are optional
- if (!IsEveryDataMemberOptional(dataContract.Members))
- return false;
- }
- }
- else if (dataContract.Members == null)
- {
- // check that all the datamembers in Members are optional
- if (!IsEveryDataMemberOptional(Members))
- return false;
- }
- else
- {
- Dictionary<string, DataMember> membersDictionary = new Dictionary<string, DataMember>(Members.Count);
- List<DataMember> dataContractMembersList = new List<DataMember>();
- for (int i = 0; i < Members.Count; i++)
- {
- membersDictionary.Add(Members[i].Name, Members[i]);
- }
- for (int i = 0; i < dataContract.Members.Count; i++)
- {
- // check that all datamembers common to both datacontracts match
- DataMember dataMember;
- if (membersDictionary.TryGetValue(dataContract.Members[i].Name, out dataMember))
- {
- if (dataMember.Equals(dataContract.Members[i], checkedContracts))
- {
- membersDictionary.Remove(dataMember.Name);
- }
- else
- {
- return false;
- }
- }
- // otherwise save the non-matching datamembers for later verification
- else
- {
- dataContractMembersList.Add(dataContract.Members[i]);
- }
- }
- // check that datamembers left over from either datacontract are optional
- if (!IsEveryDataMemberOptional(membersDictionary.Values))
- return false;
- if (!IsEveryDataMemberOptional(dataContractMembersList))
- return false;
- }
- }
- if (BaseContract == null)
- return (dataContract.BaseContract == null);
- else if (dataContract.BaseContract == null)
- return false;
- else
- return BaseContract.Equals(dataContract.BaseContract, checkedContracts);
- }
- }
- return false;
- }
- bool IsEveryDataMemberOptional(IEnumerable<DataMember> dataMembers)
- {
- foreach (DataMember dataMember in dataMembers)
- {
- if (dataMember.IsRequired)
- return false;
- }
- return true;
- }
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- internal class DataMemberComparer : IComparer<DataMember>
- {
- public int Compare(DataMember x, DataMember y)
- {
- int orderCompare = x.Order - y.Order;
- if (orderCompare != 0)
- return orderCompare;
- return String.CompareOrdinal(x.Name, y.Name);
- }
- internal static DataMemberComparer Singleton = new DataMemberComparer();
- }
- }
- }
|