/// <summary> /// Check an XmlElement to see if it includes a specific "Type" attribute. If so, return /// the actual Type associated with that attribute's value. /// </summary> /// <param name="_xml">The XmlElement containing the field's information</param> /// <param name="_defaultType"> /// If there is no Type attribute, then return this value as the "default" /// </param> /// <returns> /// NULL if no Type attribute was found, or the Type object corresponding the value of /// the Type attribute /// </returns> /// <exception cref="InvalidOperationException"> /// Thrown if there is a Type attribute, but that attribute's value cannot be turned /// into a Type object. /// </exception> private Type GetTypeFromXmlOrDefault(XmlElement _xml, Type _defaultType) { var sType = XmlExtensions.GetAttributeValue(_xml, m_context.TypeAttributeName); if (sType == null) // There is no explicit Type specifier (XmlAttribute) { return(_defaultType); } var explicitType = Lib.BetterGetType(sType, true); if (explicitType == null) { // The XML had an explicit Type, but that Type couldn't be found. So... If we // are trying to deserialize a Type that uses EntitySemantics, we assume that // the destination Type is sufficient to figure out what to deserialize. If the // destination Type is wholly inadequate to "receive" the data in the XML, the // application is at fault. For Entities, this type of mismatch is OK. if (CEntityTypeData.UsesEntitySemantics(_defaultType)) { return(_defaultType); } // However, if this isn't using EntitySemantics, then throw an exception as the // Type is unknown. throw new XDeserializationError("An Attribute was found for an Explicit Type, but it could not be turned into a Type: " + sType); } return(explicitType); }
/// <summary> /// Apply any surrogates to the object for serialization /// </summary> /// <param name="_object">The object that may be serialized with a surrogate</param> /// <param name="_elementForObject"> /// The XmlElement that is to receive the object data /// </param> /// <param name="_useType"> /// The Type that the object should be treated as. If NULL, use object.GetType() /// </param> /// <returns> /// TRUE if the serialziation was completed by a surrogate, FALSE if the framework /// should do its job. /// </returns> private bool ApplySurrogates(object _object, XmlElement _elementForObject, Type _useType) { // If nothing is sent in, then do nothing. if (_object == null) { return(false); } // Duplicate References are a "special" kind of built-in surrogate- If this object // has been serialized before, then simply refer to that version and return true. if (HandleDuplicateReferences(_object, _elementForObject)) { return(true); } // Setup var oType = _useType ?? _object.GetType(); var isComplete = false; // Check if the object is a dynamic proxy created by Entity Framework if (CEntityTypeData.UsesEntitySemantics(oType)) { // There are important conventions and differences when dealing with Entities SerializeUsingEntitySemantics(_object, oType, _elementForObject); return(true); } // Check the external surrogate var externalSurrogate = GetExternalSurrogate(oType); if (externalSurrogate != null) { isComplete = externalSurrogate.Serialize(_object, _useType, _elementForObject, this); } if (isComplete) { return(true); } // Check implicit surrogates var typeData = CTypeData.GetTypeData(oType); var impSurrogate = typeData.ImplicitSurrogate; if (impSurrogate != null) { isComplete = impSurrogate.Serialize(_object, _elementForObject, this); } return(isComplete); }
/// <summary> /// Check to see if there are surrogates that handle the deserialization. /// </summary> /// <param name="_xml">The XML containing the object data</param> /// <param name="_type">The TYPE that we're trying to deserialize</param> /// <param name="_workingObject"> /// A "Working Object" that deserializers use to determine if they need to create a new /// object or if they have an object that they can deserialize into. /// </param> /// <returns> /// TRUE if a surrogate was successful in completing the deserialization of the object, /// or FALSE if the surrogates were not able to complete all deserialization /// </returns> private bool ApplySurrogates(XmlElement _xml, Type _type, CWorkingObject _workingObject) { var isComplete = false; _workingObject.WorkingType = _type; // Check for EntitySemantics as a special and overriding Surrogate method The // UseEntitySemantics on the XML element is ignored, as the destination Type gets to // define how it gets deserialized (the attribute may be little more than a Hint to // what happened at serializatiion time) See for more information on EntitySemantics if (CEntityTypeData.UsesEntitySemantics(_type)) { DeserializeUsingEntitySemantics(_xml, _type, _workingObject); return(true); } // Check for external surrogates var externalSurrogate = GetExternalSurrogate(_type); if (externalSurrogate != null) { isComplete = externalSurrogate.Deserialize(_workingObject, _xml, this); } if (isComplete) { return(true); } // Check the Implicit surrogates if the External surrogate(s) didn't finish the // deserialization var typeData = CTypeData.GetTypeData(_type); var implicitSurrogate = typeData.ImplicitSurrogate; if (implicitSurrogate != null && implicitSurrogate.HasSurrogate) { isComplete = implicitSurrogate.Deserialize(_workingObject, _xml, this); } if (isComplete) { return(true); } return(false); }