Esempio n. 1
0
        private void AddSchemaTypeProperty(XmlDictionaryWriter writer, PropertyInfo property, TypeToBuild parentTypeToBuild)
        {
            var createListWithoutProxyType = false;
            var toBuild = new TypeToBuild(property.PropertyType);

            var arrayItem = property.GetCustomAttribute <XmlArrayItemAttribute>();

            if (arrayItem != null && !string.IsNullOrWhiteSpace(arrayItem.ElementName))
            {
                toBuild.ChildElementName = arrayItem.ElementName;
            }

            var elementItem = property.GetCustomAttribute <XmlElementAttribute>();

            if (elementItem != null && !string.IsNullOrWhiteSpace(elementItem.ElementName))
            {
                toBuild.ChildElementName   = elementItem.ElementName;
                createListWithoutProxyType = toBuild.Type.IsEnumerableType();
            }

            var attributeItem = property.GetCustomAttribute <XmlAttributeAttribute>();
            var messageBodyMemberAttribute = property.GetCustomAttribute <MessageBodyMemberAttribute>();

            if (attributeItem != null)
            {
                var name = attributeItem.AttributeName;
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = property.Name;
                }

                AddSchemaType(writer, toBuild, name, isAttribute: true);
            }
            else if (messageBodyMemberAttribute != null)
            {
                var name = messageBodyMemberAttribute.Name;
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = property.Name;
                }

                AddSchemaType(writer, toBuild, name, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType);
            }
            else
            {
                AddSchemaType(writer, toBuild, parentTypeToBuild.ChildElementName ?? property.Name, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType);
            }
        }
Esempio n. 2
0
        private void SetUniqueNameForDynamicType(TypeToBuild dynamicType)
        {
            if (!_requestedDynamicTypes.TryGetValue(dynamicType.TypeName, out var elementsList))
            {
                var elementsMap = new Dictionary <string, string> {
                    { dynamicType.ChildElementName, "" }
                };
                _requestedDynamicTypes.Add(dynamicType.TypeName, elementsMap);
                return;
            }

            if (elementsList.TryGetValue(dynamicType.ChildElementName, out var assotiatedPostfix))
            {
                dynamicType.TypeName += $"{assotiatedPostfix}";
            }
            else
            {
                var newPostfix = $"{elementsList.Count}";
                dynamicType.TypeName += $"{newPostfix}";
                elementsList.Add(dynamicType.ChildElementName, newPostfix);
            }
        }
Esempio n. 3
0
        private void AddSchemaType(XmlDictionaryWriter writer, TypeToBuild toBuild, string name, bool isArray = false, string @namespace = null, bool isAttribute = false, bool isListWithoutWrapper = false)
        {
            var type     = toBuild.Type;
            var typeInfo = type.GetTypeInfo();

            if (typeInfo.IsByRef)
            {
                type = typeInfo.GetElementType();
            }

            var typeName = type.GetSerializedTypeName();

            if (writer.TryAddSchemaTypeFromXmlSchemaProviderAttribute(type, name, SoapSerializer.XmlSerializer, _xmlNamespaceManager))
            {
                return;
            }

            var underlyingType = Nullable.GetUnderlyingType(type);

            //if type is a nullable non-system struct
            if (underlyingType?.IsValueType == true && !underlyingType.IsEnum && underlyingType.Namespace != null && underlyingType.Namespace != "System" && !underlyingType.Namespace.StartsWith("System."))
            {
                AddSchemaType(writer, new TypeToBuild(underlyingType)
                {
                    ChildElementName = toBuild.TypeName
                }, name, isArray, @namespace, isAttribute);
                return;
            }

            writer.WriteStartElement(isAttribute ? "attribute" : "element", Namespaces.XMLNS_XSD);

            // Check for null, since we may use empty NS
            if (@namespace != null)
            {
                writer.WriteAttributeString("targetNamespace", @namespace);
            }
            else if (typeInfo.IsEnum || underlyingType?.IsEnum == true ||
                     (typeInfo.IsValueType && typeInfo.Namespace != null && (typeInfo.Namespace == "System" || typeInfo.Namespace.StartsWith("System."))) ||
                     (type.Name == "String") ||
                     (type.Name == "Byte[]")
                     )
            {
                XmlQualifiedName xsTypename;
                if (typeof(DateTimeOffset).IsAssignableFrom(type))
                {
                    if (string.IsNullOrEmpty(name))
                    {
                        name = typeName;
                    }

                    Namespaces.AddNamespaceIfNotAlreadyPresentAndGetPrefix(_xmlNamespaceManager, "nsdto", Namespaces.SYSTEM_NS);
                    xsTypename = new XmlQualifiedName(typeName, Namespaces.SYSTEM_NS);

                    _buildDateTimeOffset = true;
                }
                else if (typeInfo.IsEnum)
                {
                    xsTypename = new XmlQualifiedName(typeName, _xmlNamespaceManager.LookupNamespace("tns"));
                    _enumToBuild.Enqueue(type);
                }
                else if (underlyingType?.IsEnum == true)
                {
                    xsTypename = new XmlQualifiedName(underlyingType.GetSerializedTypeName(), _xmlNamespaceManager.LookupNamespace("tns"));
                    _enumToBuild.Enqueue(underlyingType);
                }
                else
                {
                    if (underlyingType != null)
                    {
                        xsTypename = ResolveType(underlyingType);
                        writer.WriteAttributeString("nillable", "true");
                    }
                    else
                    {
                        xsTypename = ResolveType(type);
                    }
                }

                if (isAttribute)
                {
                    // skip occurence
                }
                else if (isArray)
                {
                    writer.WriteAttributeString("minOccurs", "0");
                    writer.WriteAttributeString("maxOccurs", "unbounded");
                    writer.WriteAttributeString("nillable", "true");
                }
                else
                {
                    writer.WriteAttributeString("minOccurs", type.IsValueType ? "1" : "0");
                    writer.WriteAttributeString("maxOccurs", "1");
                }

                if (string.IsNullOrEmpty(name))
                {
                    name = xsTypename.Name;
                }

                writer.WriteAttributeString("name", name);
                writer.WriteAttributeString("type", $"{_xmlNamespaceManager.LookupPrefix(xsTypename.Namespace)}:{xsTypename.Name}");
            }
            else
            {
                var newTypeToBuild = new TypeToBuild(type);

                if (!string.IsNullOrWhiteSpace(toBuild.ChildElementName))
                {
                    newTypeToBuild.ChildElementName = toBuild.ChildElementName;
                    SetUniqueNameForDynamicType(newTypeToBuild);
                }

                writer.WriteAttributeString("minOccurs", "0");
                if (isArray)
                {
                    writer.WriteAttributeString("maxOccurs", "unbounded");
                    writer.WriteAttributeString("nillable", "true");
                }
                else
                {
                    writer.WriteAttributeString("maxOccurs", "1");
                }
                if (type == typeof(Stream) || typeof(Stream).IsAssignableFrom(type))
                {
                    name = "StreamBody";

                    writer.WriteAttributeString("name", name);
                    writer.WriteAttributeString("type", $"{_xmlNamespaceManager.LookupPrefix(Namespaces.XMLNS_XSD)}:base64Binary");
                }
                else if (type.IsArray)
                {
                    if (string.IsNullOrEmpty(name))
                    {
                        name = typeName;
                    }

                    writer.WriteAttributeString("name", name);
                    writer.WriteAttributeString("type", "tns:" + newTypeToBuild.TypeName);

                    _complexTypeToBuild.Enqueue(newTypeToBuild);
                }
                else if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    if (type.GetGenericType().Name == "String")
                    {
                        if (string.IsNullOrEmpty(name))
                        {
                            name = typeName;
                        }

                        var ns = $"q{_namespaceCounter++}";

                        writer.WriteXmlnsAttribute(ns, Namespaces.ARRAYS_NS);
                        writer.WriteAttributeString("name", name);
                        writer.WriteAttributeString("nillable", "true");

                        writer.WriteAttributeString("type", $"{ns}:{newTypeToBuild.TypeName}");

                        _arrayToBuild.Enqueue(type);
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(name))
                        {
                            name = typeName;
                        }

                        writer.WriteAttributeString("name", name);

                        if (!isArray)
                        {
                            writer.WriteAttributeString("nillable", "true");
                        }

                        if (isListWithoutWrapper)
                        {
                            newTypeToBuild = new TypeToBuild(newTypeToBuild.Type.GetGenericType());
                        }

                        if (newTypeToBuild.IsAnonumous)
                        {
                            AddSchemaComplexType(writer, newTypeToBuild);
                        }
                        else
                        {
                            writer.WriteAttributeString("type", "tns:" + newTypeToBuild.TypeName);

                            _complexTypeToBuild.Enqueue(newTypeToBuild);
                        }
                    }
                }
                else if (toBuild.IsAnonumous)
                {
                    writer.WriteAttributeString("name", name);
                    AddSchemaComplexType(writer, newTypeToBuild);
                }
                else
                {
                    if (string.IsNullOrEmpty(name))
                    {
                        name = typeName;
                    }

                    writer.WriteAttributeString("name", name);
                    writer.WriteAttributeString("type", "tns:" + newTypeToBuild.TypeName);

                    _complexTypeToBuild.Enqueue(newTypeToBuild);
                }
            }

            writer.WriteEndElement();             // element
        }
Esempio n. 4
0
        private void AddSchemaTypeProperty(XmlDictionaryWriter writer, PropertyInfo property, TypeToBuild parentTypeToBuild)
        {
            if (property.IsChoice())
            {
                writer.WriteStartElement("choice", Namespaces.XMLNS_XSD);

                if (property.PropertyType.IsEnumerableType())
                {
                    writer.WriteAttributeString("minOccurs", "0");
                    writer.WriteAttributeString("maxOccurs", "unbounded");
                }

                var choiceElements = property.GetCustomAttributes <XmlElementAttribute>();
                foreach (var choiceElement in choiceElements)
                {
                    if (choiceElement != null)
                    {
                        AddSchemaType(writer, choiceElement.Type ?? property.PropertyType, choiceElement.ElementName ?? property.Name);
                    }
                }

                writer.WriteEndElement();                 // choice
                return;
            }

            var createListWithoutProxyType = false;
            var toBuild = new TypeToBuild(property.PropertyType);

            var arrayItem = property.GetCustomAttribute <XmlArrayItemAttribute>();

            if (arrayItem != null && !string.IsNullOrWhiteSpace(arrayItem.ElementName))
            {
                toBuild.ChildElementName = arrayItem.ElementName;
            }

            var elementItem = property.GetCustomAttribute <XmlElementAttribute>();

            if (elementItem != null && !string.IsNullOrWhiteSpace(elementItem.ElementName))
            {
                toBuild.ChildElementName   = elementItem.ElementName;
                createListWithoutProxyType = toBuild.Type.IsEnumerableType();
            }

            var attributeItem = property.GetCustomAttribute <XmlAttributeAttribute>();
            var messageBodyMemberAttribute = property.GetCustomAttribute <MessageBodyMemberAttribute>();

            if (attributeItem != null)
            {
                var name = attributeItem.AttributeName;
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = property.Name;
                }

                AddSchemaType(writer, toBuild, name, isAttribute: true);
            }
            else if (messageBodyMemberAttribute != null)
            {
                var name = messageBodyMemberAttribute.Name;
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = property.Name;
                }

                AddSchemaType(writer, toBuild, name, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType);
            }
            else
            {
                AddSchemaType(writer, toBuild, parentTypeToBuild.ChildElementName ?? property.Name, isArray: createListWithoutProxyType, isListWithoutWrapper: createListWithoutProxyType);
            }
        }
Esempio n. 5
0
        private void AddSchemaComplexType(XmlDictionaryWriter writer, TypeToBuild toBuild)
        {
            var toBuildType       = toBuild.Type;
            var toBuildBodyType   = GetMessageContractBodyType(toBuildType);
            var isWrappedBodyType = IsWrappedMessageContractType(toBuildType);
            var toBuildName       = toBuild.TypeName;

            if (toBuild.IsAnonumous || !_builtComplexTypes.Contains(toBuildName))
            {
                writer.WriteStartElement("complexType", Namespaces.XMLNS_XSD);

                if (!toBuild.IsAnonumous)
                {
                    writer.WriteAttributeString("name", toBuildName);
                }

                if (toBuildType.IsArray)
                {
                    writer.WriteStartElement("sequence", Namespaces.XMLNS_XSD);
                    AddSchemaType(writer, toBuildType.GetElementType(), toBuild.ChildElementName, true);
                    writer.WriteEndElement();                     // sequence
                }
                else if (typeof(IEnumerable).IsAssignableFrom(toBuildType))
                {
                    writer.WriteStartElement("sequence", Namespaces.XMLNS_XSD);
                    AddSchemaType(writer, toBuildType.GetGenericType(), toBuild.ChildElementName, true);
                    writer.WriteEndElement();                     // sequence
                }
                else
                {
                    if (!isWrappedBodyType)
                    {
                        var properties = toBuildBodyType.GetProperties().Where(prop => !prop.IsIgnored())
                                         .ToList();

                        var elements = properties.Where(t => !t.IsAttribute()).ToList();
                        if (elements.Any())
                        {
                            writer.WriteStartElement("sequence", Namespaces.XMLNS_XSD);
                            foreach (var element in elements)
                            {
                                AddSchemaTypeProperty(writer, element, toBuild);
                            }

                            writer.WriteEndElement();                             // sequence
                        }

                        var attributes = properties.Where(t => t.IsAttribute());
                        foreach (var attribute in attributes)
                        {
                            AddSchemaTypeProperty(writer, attribute, toBuild);
                        }
                    }
                    else
                    {
                        var properties = toBuildType.GetProperties().Where(prop => !prop.IsIgnored())
                                         .ToList();

                        var elements = properties.Where(t => !t.IsAttribute()).ToList();
                        if (elements.Any())
                        {
                            writer.WriteStartElement("sequence", Namespaces.XMLNS_XSD);
                            foreach (var element in elements)
                            {
                                AddSchemaTypeProperty(writer, element, toBuild);
                            }

                            writer.WriteEndElement();                             // sequence
                        }

                        var attributes = properties.Where(t => t.IsAttribute());
                        foreach (var attribute in attributes)
                        {
                            AddSchemaTypeProperty(writer, attribute, toBuild);
                        }

                        var messageBodyMemberFields = toBuildType.GetFields()
                                                      .Where(field => field.CustomAttributes.Any(attr => attr.AttributeType == typeof(MessageBodyMemberAttribute)))
                                                      .OrderBy(field => field.GetCustomAttribute <MessageBodyMemberAttribute>().Order);

                        foreach (var field in messageBodyMemberFields)
                        {
                            var messageBodyMember = field.GetCustomAttribute <MessageBodyMemberAttribute>();

                            var fieldName = messageBodyMember.Name ?? field.Name;

                            AddSchemaType(writer, field.FieldType, fieldName);
                        }
                    }
                }

                writer.WriteEndElement();                 // complexType

                if (isWrappedBodyType)
                {
                    writer.WriteStartElement("element", Namespaces.XMLNS_XSD);
                    writer.WriteAttributeString("name", toBuildName);
                    writer.WriteAttributeString("nillable", "true");
                    writer.WriteAttributeString("type", "tns:" + toBuildName);
                    writer.WriteEndElement();                     // element
                }

                _builtComplexTypes.Add(toBuildName);
            }
        }