private void DeserializeContents(WorkflowMarkupSerializationManager serializationManager, object obj, XmlReader reader) { if (serializationManager == null) throw new ArgumentNullException("serializationManager"); if (obj == null) throw new ArgumentNullException("obj"); if (reader == null) throw new ArgumentNullException("reader"); if (reader.NodeType != XmlNodeType.Element) return; // get the serializer WorkflowMarkupSerializer serializer = serializationManager.GetSerializer(obj.GetType(), typeof(WorkflowMarkupSerializer)) as WorkflowMarkupSerializer; if (serializer == null) { serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerNotAvailable, obj.GetType().FullName), reader)); return; } try { serializer.OnBeforeDeserialize(serializationManager, obj); } catch (Exception e) { serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e)); return; } bool isEmptyElement = reader.IsEmptyElement; string elementNamespace = reader.NamespaceURI; List<PropertyInfo> props = new List<PropertyInfo>(); List<EventInfo> events = new List<EventInfo>(); // Add the extended properties for primitive types if (obj.GetType().IsPrimitive || obj.GetType() == typeof(string) || obj.GetType() == typeof(decimal) || obj.GetType().IsEnum || obj.GetType() == typeof(DateTime) || obj.GetType() == typeof(TimeSpan) || obj.GetType() == typeof(Guid)) { props.AddRange(serializationManager.GetExtendedProperties(obj)); } else { try { props.AddRange(serializer.GetProperties(serializationManager, obj)); props.AddRange(serializationManager.GetExtendedProperties(obj)); events.AddRange(serializer.GetEvents(serializationManager, obj)); } catch (Exception e) { serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerThrewException, obj.GetType(), e.Message), e, reader)); return; } } //First we try to deserialize simple properties if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { // if (reader.LocalName.Equals("xmlns", StringComparison.Ordinal) || reader.Prefix.Equals("xmlns", StringComparison.Ordinal)) continue; // XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix)); if (xmlQualifiedName.Namespace.Equals(StandardXomlKeys.Definitions_XmlNs, StringComparison.Ordinal) && !IsMarkupExtension(xmlQualifiedName) && !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, props, xmlQualifiedName) && !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, xmlQualifiedName)) { serializationManager.FireFoundDefTag(new WorkflowMarkupElementEventArgs(reader)); continue; } //For simple properties we assume that if . indicates string propName = XmlConvert.DecodeName(reader.LocalName); string propVal = reader.Value; DependencyProperty dependencyProperty = ResolveDependencyProperty(serializationManager, reader, obj, propName); if (dependencyProperty != null) { serializationManager.Context.Push(dependencyProperty); try { if (dependencyProperty.IsEvent) DeserializeEvent(serializationManager, reader, obj, propVal); else DeserializeSimpleProperty(serializationManager, reader, obj, propVal); } finally { Debug.Assert(serializationManager.Context.Current == dependencyProperty, "Serializer did not remove an object it pushed into stack."); serializationManager.Context.Pop(); } } else { PropertyInfo property = WorkflowMarkupSerializer.LookupProperty(props, propName); if (property != null) { serializationManager.Context.Push(property); try { DeserializeSimpleProperty(serializationManager, reader, obj, propVal); } finally { Debug.Assert((PropertyInfo)serializationManager.Context.Current == property, "Serializer did not remove an object it pushed into stack."); serializationManager.Context.Pop(); } } else { EventInfo evt = WorkflowMarkupSerializer.LookupEvent(events, propName); if (events != null && evt != null) { serializationManager.Context.Push(evt); try { DeserializeEvent(serializationManager, reader, obj, propVal); } finally { Debug.Assert((EventInfo)serializationManager.Context.Current == evt, "Serializer did not remove an object it pushed into stack."); serializationManager.Context.Pop(); } } else serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerNoMemberFound, new object[] { propName, obj.GetType().FullName }), reader)); } } } } try { serializer.OnBeforeDeserializeContents(serializationManager, obj); } catch (Exception e) { serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e)); return; } //Now deserialize compound properties try { serializer.ClearChildren(serializationManager, obj); } catch (Exception e) { serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_SerializerThrewException, obj.GetType(), e.Message), e, reader)); return; } using (ContentProperty contentProperty = new ContentProperty(serializationManager, serializer, obj)) { List<ContentInfo> contents = new List<ContentInfo>(); if (!isEmptyElement) { reader.MoveToElement(); int initialDepth = reader.Depth; XmlQualifiedName extendedPropertyQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix)); do { // Extended property should be deserialized, this is required for primitive types which have extended property as children // We should not ignore if (extendedPropertyQualifiedName != null && !ExtendedPropertyInfo.IsExtendedProperty(serializationManager, extendedPropertyQualifiedName)) { extendedPropertyQualifiedName = null; continue; } // this will make it to skip all the nodes if ((initialDepth + 1) < reader.Depth) { bool unnecessaryXmlFound = false; while (reader.Read() && ((initialDepth + 1) < reader.Depth)) { // Ignore comments and whitespaces if (reader.NodeType != XmlNodeType.Comment && reader.NodeType != XmlNodeType.Whitespace && !unnecessaryXmlFound) { serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidDataFoundForType, obj.GetType().FullName), reader)); unnecessaryXmlFound = true; } } } //Push all the PIs into stack so that they are available for type resolution AdvanceReader(reader); if (reader.NodeType == XmlNodeType.Element) { //We should only support A.B syntax for compound properties, all others are treated as content XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.LocalName, reader.LookupNamespace(reader.Prefix)); int index = reader.LocalName.IndexOf('.'); if (index > 0 || ExtendedPropertyInfo.IsExtendedProperty(serializationManager, xmlQualifiedName)) { string propertyName = reader.LocalName.Substring(reader.LocalName.IndexOf('.') + 1); PropertyInfo property = WorkflowMarkupSerializer.LookupProperty(props, propertyName); DependencyProperty dependencyProperty = ResolveDependencyProperty(serializationManager, reader, obj, reader.LocalName); if (dependencyProperty == null && property == null) serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidElementFoundForType, reader.LocalName, obj.GetType().FullName), reader)); else if (dependencyProperty != null) { PropertyInfo prop = WorkflowMarkupSerializer.LookupProperty(props, dependencyProperty.Name); //Deserialize the dynamic property serializationManager.Context.Push(dependencyProperty); try { DeserializeCompoundProperty(serializationManager, reader, obj); } finally { Debug.Assert(serializationManager.Context.Current == dependencyProperty, "Serializer did not remove an object it pushed into stack."); serializationManager.Context.Pop(); } } else if (property != null) { //Deserialize the compound property serializationManager.Context.Push(property); try { DeserializeCompoundProperty(serializationManager, reader, obj); } finally { Debug.Assert((PropertyInfo)serializationManager.Context.Current == property, "Serializer did not remove an object it pushed into stack."); serializationManager.Context.Pop(); } } } else { //Deserialize the children int lineNumber = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LineNumber : 1; int linePosition = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LinePosition : 1; object obj2 = DeserializeObject(serializationManager, reader); if (obj2 != null) { obj2 = GetValueFromMarkupExtension(serializationManager, obj2); if (obj2 != null && obj2.GetType() == typeof(string) && ((string)obj2).StartsWith("{}", StringComparison.Ordinal)) obj2 = ((string)obj2).Substring(2); contents.Add(new ContentInfo(obj2, lineNumber, linePosition)); } } } else if (reader.NodeType == XmlNodeType.Text && contentProperty.Property != null) { //If we read the string then we should not advance the reader further instead break int lineNumber = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LineNumber : 1; int linePosition = (reader is IXmlLineInfo) ? ((IXmlLineInfo)reader).LinePosition : 1; contents.Add(new ContentInfo(reader.ReadString(), lineNumber, linePosition)); if (initialDepth >= reader.Depth) break; } else { if (reader.NodeType == XmlNodeType.Entity || reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.CDATA) serializationManager.ReportError(CreateSerializationError(SR.GetString(SR.Error_InvalidDataFound, reader.Value.Trim(), obj.GetType().FullName), reader)); } } while (reader.Read() && initialDepth < reader.Depth); } //Make sure that we set contents contentProperty.SetContents(contents); } try { serializer.OnAfterDeserialize(serializationManager, obj); } catch (Exception e) { serializationManager.ReportError(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_SerializerThrewException, obj.GetType().FullName, e.Message), e)); return; } }