예제 #1
0
        private object DeserializeArrayXmlSerializer(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, ICustomAttributeProvider customAttributeProvider)
        {
            var xmlArrayAttributes = customAttributeProvider.GetCustomAttributes(typeof(XmlArrayItemAttribute), true);
            XmlArrayItemAttribute xmlArrayItemAttribute = xmlArrayAttributes.FirstOrDefault() as XmlArrayItemAttribute;
            var xmlElementAttributes = customAttributeProvider.GetCustomAttributes(typeof(XmlElementAttribute), true);
            XmlElementAttribute xmlElementAttribute = xmlElementAttributes.FirstOrDefault() as XmlElementAttribute;

            var isEmpty             = xmlReader.IsEmptyElement;
            var hasContainerElement = xmlElementAttribute == null;

            if (hasContainerElement)
            {
                xmlReader.ReadStartElement(parameterName, parameterNs);
            }

            var elementType = parameterType.GetElementType();

            var arrayItemName = xmlArrayItemAttribute?.ElementName ?? xmlElementAttribute?.ElementName ?? elementType.Name;

            if (xmlArrayItemAttribute?.ElementName == null && elementType.Namespace?.StartsWith("System") == true)
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                arrayItemName = compiler.GetTypeOutput(type);
            }

            var deserializeMethod  = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var arrayItemNamespace = xmlArrayItemAttribute?.Namespace ?? parameterNs;

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, arrayItemName, arrayItemNamespace);

            object result = null;

            lock (serializer)
            {
                if (xmlReader.HasValue && elementType?.FullName == "System.Byte")
                {
                    result = xmlReader.ReadContentAsBase64();
                }
                else
                {
                    result = deserializeMethod.Invoke(null, new object[] { serializer, arrayItemName, arrayItemNamespace, xmlReader });
                }
            }

            if (!isEmpty && hasContainerElement)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
        private object DeserializeObject(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs)
        {
            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
            var elementType = parameterType.GetElementType();

            if (elementType == null || parameterType.IsArray)
            {
                elementType = parameterType;
            }

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);

            lock (serializer)
            {
                return(serializer.Deserialize(xmlReader));
            }
        }
예제 #3
0
        private object DeserializeArray(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, SoapMethodParameterInfo parameterInfo)
        {
            var isEmpty = xmlReader.IsEmptyElement;
            //if (parameterInfo.ArrayItemName != null)
            {
                xmlReader.ReadStartElement(parameterName, parameterNs);
            }

            var elementType = parameterType.GetElementType();

            var localName = parameterInfo.ArrayItemName ?? elementType.Name;

            if (parameterInfo.ArrayItemName == null && elementType.Namespace.StartsWith("System"))
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                localName = compiler.GetTypeOutput(type);
            }

            //localName = "ComplexModelInput";
            var deserializeMethod = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var serializer        = CachedXmlSerializer.GetXmlSerializer(elementType, localName, parameterNs);

            object result = null;

            lock (serializer)
            {
                result = deserializeMethod.Invoke(null, new object[] { serializer, localName, parameterNs, xmlReader });
            }

            //if (parameterInfo.ArrayItemName != null)
            if (!isEmpty)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
예제 #4
0
        private object DeserializeArrayXmlSerializer(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, MemberInfo memberInfo)
        {
            XmlArrayItemAttribute xmlArrayItemAttribute = memberInfo.GetCustomAttribute(typeof(XmlArrayItemAttribute)) as XmlArrayItemAttribute;

            var isEmpty = xmlReader.IsEmptyElement;

            xmlReader.ReadStartElement(parameterName, parameterNs);

            var elementType = parameterType.GetElementType();

            var arrayItemName = xmlArrayItemAttribute?.ElementName ?? elementType.Name;

            if (xmlArrayItemAttribute?.ElementName == null && elementType.Namespace?.StartsWith("System") == true)
            {
                var compiler = new CSharpCodeProvider();
                var type     = new CodeTypeReference(elementType);
                arrayItemName = compiler.GetTypeOutput(type);
            }

            var deserializeMethod  = typeof(XmlSerializerExtensions).GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), elementType);
            var arrayItemNamespace = xmlArrayItemAttribute?.Namespace ?? parameterNs;

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, arrayItemName, arrayItemNamespace);

            object result = null;

            lock (serializer)
            {
                result = deserializeMethod.Invoke(null, new object[] { serializer, arrayItemName, arrayItemNamespace, xmlReader });
            }

            if (!isEmpty)
            {
                xmlReader.ReadEndElement();
            }

            return(result);
        }
예제 #5
0
        private static object DeserializeObject(System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs)
        {
            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
            var elementType = parameterType.GetElementType();

            if (elementType == null || parameterType.IsArray)
            {
                elementType = parameterType;
            }

            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);

            lock (serializer)
            {
                if (elementType == typeof(Stream) || typeof(Stream).IsAssignableFrom(elementType))
                {
                    xmlReader.Read();
                    return(new MemoryStream(xmlReader.ReadContentAsBase64()));
                }

                return(serializer.Deserialize(xmlReader));
            }
        }
예제 #6
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, ref Dictionary <string, object> outArgs)
        {
            var parameters = operation.NormalParameters;
            // avoid reallocation
            var arguments = new List <object>(parameters.Length + operation.OutParameters.Length);

            // Find the element for the operation's data
            xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);

            for (int i = 0; i < parameters.Length; i++)
            {
                var parameterName = parameters[i].Name;
                var parameterNs   = parameters[i].Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        var elementType = parameters[i].Parameter.ParameterType.GetElementType();
                        if (elementType == null || parameters[i].Parameter.ParameterType.IsArray)
                        {
                            elementType = parameters[i].Parameter.ParameterType;
                        }

                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                            lock (serializer)
                                arguments.Add(serializer.Deserialize(xmlReader));
                        }
                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments.Add(serializer.ReadObject(xmlReader, verifyObjectName: true));
                        }
                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    arguments.Add(null);
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    outArgs[parameterInfo.Name] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    outArgs[parameterInfo.Name] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    outArgs[parameterInfo.Name] = Activator.CreateInstance(type);
                }
            }
            return(arguments.ToArray());
        }
예제 #7
0
        private void OnWriteXmlSerializerBodyContents(XmlDictionaryWriter writer)
        {
            Debug.Assert(_outResults != null, "Object should set empty out results");

            // Do not wrap old-style single element response into additional xml element for xml serializer
            var needResponseEnvelope = _result == null || (_outResults.Count > 0) || !_operation.IsMessageContractResponse;

            if (needResponseEnvelope)
            {
                writer.WriteStartElement(_envelopeName, _serviceNamespace);
            }

            foreach (var outResult in _outResults)
            {
                string value = null;
                if (outResult.Value is Guid)
                {
                    value = outResult.Value.ToString();
                }
                else if (outResult.Value is bool)
                {
                    value = outResult.Value.ToString().ToLower();
                }
                else if (outResult.Value is string)
                {
                    value = System.Security.SecurityElement.Escape(outResult.Value.ToString());
                }
                else if (outResult.Value is Enum)
                {
                    value = outResult.Value.ToString();
                }
                else if (outResult.Value == null)
                {
                    value = null;
                }
                else
                {
                    //for complex types
                    using (var ms = new MemoryStream())
                        using (var stream = new BufferedStream(ms))
                        {
                            // write element with name as outResult.Key and type information as outResultType
                            // i.e. <outResult.Key xsi:type="outResultType" ... />
                            var outResultType = outResult.Value.GetType();
                            var serializer    = CachedXmlSerializer.GetXmlSerializer(outResultType, outResult.Key, _serviceNamespace);
                            lock (serializer)
                            {
                                serializer.Serialize(stream, outResult.Value);
                            }

                            //add outResultType. ugly, but working
                            stream.Position = 0;
                            XmlDocument xdoc = new XmlDocument();
                            xdoc.Load(stream);
                            var attr = xdoc.CreateAttribute("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance");
                            attr.Value = outResultType.Name;
                            xdoc.DocumentElement.Attributes.Prepend(attr);
                            writer.WriteRaw(xdoc.DocumentElement.OuterXml);
                        }
                }

                if (value != null)
                {
                    writer.WriteRaw(string.Format("<{0}>{1}</{0}>", outResult.Key, value));
                }
            }

            if (_result != null)
            {
                // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                var resultType = _result.GetType();

                var xmlRootAttr = resultType.GetTypeInfo().GetCustomAttributes <XmlRootAttribute>().FirstOrDefault();

                var xmlName = _operation.ReturnElementName
                              ?? (needResponseEnvelope
                                        ? _resultName
                                        : (string.IsNullOrWhiteSpace(xmlRootAttr?.ElementName)
                                        ? resultType.Name
                                        : xmlRootAttr.ElementName));

                var xmlNs = _operation.ReturnNamespace
                            ?? (string.IsNullOrWhiteSpace(xmlRootAttr?.Namespace)
                                        ? _serviceNamespace
                                        : xmlRootAttr.Namespace);

                var xmlArrayAttr = _operation.DispatchMethod.GetCustomAttribute <XmlArrayAttribute>();

                if (xmlArrayAttr != null && resultType.IsArray)
                {
                    var serializer = CachedXmlSerializer.GetXmlSerializer(resultType.GetElementType(), xmlName, xmlNs);

                    lock (serializer)
                    {
                        serializer.SerializeArray(writer, (object[])_result);
                    }
                }
                else
                {
                    var messageContractAttribute = resultType.GetCustomAttribute <MessageContractAttribute>();

                    // This behavior is opt-in i.e. you have to explicitly have a [MessageContract(IsWrapped=false)]
                    // to have the message body members inlined.
                    var shouldInline = messageContractAttribute != null && messageContractAttribute.IsWrapped == false;

                    if (shouldInline)
                    {
                        var memberInformation = resultType
                                                .GetPropertyOrFieldMembers()
                                                .Select(mi => new
                        {
                            Member = mi,
                            MessageBodyMemberAttribute = mi.GetCustomAttribute <MessageBodyMemberAttribute>()
                        })
                                                .OrderBy(x => x.MessageBodyMemberAttribute?.Order ?? 0);

                        foreach (var memberInfo in memberInformation)
                        {
                            var memberType  = memberInfo.Member.GetPropertyOrFieldType();
                            var memberValue = memberInfo.Member.GetPropertyOrFieldValue(_result);

                            var memberName      = memberInfo.MessageBodyMemberAttribute?.Name ?? memberInfo.Member.Name;
                            var memberNamespace = memberInfo.MessageBodyMemberAttribute?.Namespace ?? xmlNs;

                            var serializer = CachedXmlSerializer.GetXmlSerializer(memberType, memberName, memberNamespace);

                            lock (serializer)
                            {
                                serializer.Serialize(writer, memberValue);
                            }
                        }
                    }
                    else
                    {
                        var serializer = CachedXmlSerializer.GetXmlSerializer(resultType, xmlName, xmlNs);

                        lock (serializer)
                        {
                            serializer.Serialize(writer, _result);
                        }
                    }
                }
            }

            if (needResponseEnvelope)
            {
                writer.WriteEndElement();
            }
        }
예제 #8
0
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            // do not wrap old-style single element response into additional xml element for xml serializer
            var needResponseEnvelope = _serializer != SoapSerializer.XmlSerializer || _result == null || (_outResults != null && _outResults.Count > 0) || !_operation.IsMessageContractResponse;

            if (needResponseEnvelope)
            {
                writer.WriteStartElement(_envelopeName, _serviceNamespace);
            }

            if (_outResults != null)
            {
                foreach (var outResult in _outResults)
                {
                    string value = null;
                    if (outResult.Value is Guid)
                    {
                        value = outResult.Value.ToString();
                    }
                    else if (outResult.Value is bool)
                    {
                        value = outResult.Value.ToString().ToLower();
                    }
                    else if (outResult.Value is string)
                    {
                        value = System.Security.SecurityElement.Escape(outResult.Value.ToString());
                    }
                    else if (outResult.Value is Enum)
                    {
                        value = outResult.Value.ToString();
                    }
                    else if (outResult.Value == null)
                    {
                        value = null;
                    }

                    //for complex types
                    else
                    {
                        using (var ms = new MemoryStream())
                            using (var stream = new BufferedStream(ms))
                            {
                                switch (_serializer)
                                {
                                case SoapSerializer.XmlSerializer:
                                    // write element with name as outResult.Key and type information as outResultType
                                    // i.e. <outResult.Key xsi:type="outResultType" ... />
                                    var outResultType = outResult.Value.GetType();
                                    var serializer    = CachedXmlSerializer.GetXmlSerializer(outResultType, outResult.Key, _serviceNamespace);
                                    lock (serializer)
                                    {
                                        serializer.Serialize(stream, outResult.Value);
                                    }

                                    //add outResultType. ugly, but working
                                    stream.Position = 0;
                                    XmlDocument xdoc = new XmlDocument();
                                    xdoc.Load(stream);
                                    var attr = xdoc.CreateAttribute("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance");
                                    attr.Value = outResultType.Name;
                                    xdoc.DocumentElement.Attributes.Prepend(attr);
                                    writer.WriteRaw(xdoc.DocumentElement.OuterXml);
                                    break;

                                case SoapSerializer.DataContractSerializer:
                                    new DataContractSerializer(outResult.Value.GetType()).WriteObject(ms, outResult.Value);
                                    stream.Position = 0;
                                    using (var reader = XmlReader.Create(stream))
                                    {
                                        reader.MoveToContent();
                                        value = reader.ReadInnerXml();
                                    }

                                    break;

                                default: throw new NotImplementedException();
                                }
                            }
                    }

                    if (value != null)
                    {
                        writer.WriteRaw(string.Format("<{0}>{1}</{0}>", outResult.Key, value));
                    }
                }
            }

            if (_result != null)
            {
                switch (_serializer)
                {
                case SoapSerializer.XmlSerializer:
                {
                    // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                    var resultType = _result.GetType();
                    var serializer = CachedXmlSerializer.GetXmlSerializer(resultType, needResponseEnvelope ? _resultName : resultType.Name, _serviceNamespace);
                    lock (serializer)
                    {
                        serializer.Serialize(writer, _result);
                    }
                }

                break;

                case SoapSerializer.DataContractSerializer:
                {
                    var serializer = new DataContractSerializer(_result.GetType(), _resultName, _serviceNamespace);
                    serializer.WriteObject(writer, _result);
                }

                break;

                default: throw new NotImplementedException();
                }
            }

            if (needResponseEnvelope)
            {
                writer.WriteEndElement();
            }
        }
예제 #9
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation)
        {
            var arguments = new object[operation.AllParameters.Length];

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);
            }

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            foreach (var parameterInfo in operation.InParameters)
            {
                var parameterName = parameterInfo.Name;
                var parameterNs   = parameterInfo.Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                        if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                        {
                            elementType = parameterInfo.Parameter.ParameterType;
                        }

                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                            var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                            lock (serializer)
                            {
                                arguments[parameterInfo.Index] = serializer.Deserialize(xmlReader);
                            }
                        }

                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments[parameterInfo.Index] = serializer.ReadObject(xmlReader, verifyObjectName: true);
                        }

                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    arguments[parameterInfo.Index] = null;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }
예제 #10
0
        private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, HttpContext httpContext)
        {
            var arguments = new object[operation.AllParameters.Length];

            // Find the element for the operation's data
            if (!operation.IsMessageContractRequest)
            {
                xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace);
            }

            // if any ordering issues, possible to rewrite like:

            /*while (!xmlReader.EOF)
             * {
             *      var parameterInfo = operation.InParameters.FirstOrDefault(p => p.Name == xmlReader.LocalName && p.Namespace == xmlReader.NamespaceURI);
             *      if (parameterInfo == null)
             *      {
             *              xmlReader.Skip();
             *              continue;
             *      }
             *      var parameterName = parameterInfo.Name;
             *      var parameterNs = parameterInfo.Namespace;
             *      ...
             * }*/

            foreach (var parameterInfo in operation.InParameters)
            {
                var parameterName = parameterInfo.Name;

                var parameterNs = parameterInfo.Namespace ?? operation.Contract.Namespace;

                if (xmlReader.IsStartElement(parameterName, parameterNs))
                {
                    xmlReader.MoveToStartElement(parameterName, parameterNs);

                    if (xmlReader.IsStartElement(parameterName, parameterNs))
                    {
                        switch (_serializer)
                        {
                        case SoapSerializer.XmlSerializer:
                        {
                            // case [XmlElement("parameter")] int parameter
                            // case int[] parameter
                            // case [XmlArray("parameter")] int[] parameter
                            if (!parameterInfo.Parameter.ParameterType.IsArray || (parameterInfo.ArrayName != null && parameterInfo.ArrayItemName == null))
                            {
                                // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                                var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                                if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                                {
                                    elementType = parameterInfo.Parameter.ParameterType;
                                }

                                var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, parameterName, parameterNs);
                                lock (serializer)
                                {
                                    arguments[parameterInfo.Index] = serializer.Deserialize(xmlReader);
                                }
                            }

                            // case [XmlElement("parameter")] int[] parameter
                            // case [XmlArray("parameter"), XmlArrayItem(ElementName = "item")] int[] parameter
                            else
                            {
                                //if (parameterInfo.ArrayItemName != null)
                                {
                                    xmlReader.ReadStartElement(parameterName, parameterNs);
                                }

                                var elementType = parameterInfo.Parameter.ParameterType.GetElementType();

                                var localName = parameterInfo.ArrayItemName ?? elementType.Name;
                                if (parameterInfo.ArrayItemName == null && elementType.Namespace.StartsWith("System"))
                                {
                                    localName = localName.ToLower();
                                }

                                //localName = "ComplexModelInput";
                                var deserializeMethod = typeof(XmlSerializerExtensions)
                                                        .GetGenericMethod(nameof(XmlSerializerExtensions.DeserializeArray), new[] { elementType });
                                var serializer = CachedXmlSerializer.GetXmlSerializer(elementType, localName, parameterNs);
                                lock (serializer)
                                {
                                    arguments[parameterInfo.Index] = deserializeMethod.Invoke(null, new object[] { serializer, localName, parameterNs, xmlReader });
                                }

                                //if (parameterInfo.ArrayItemName != null)
                                {
                                    xmlReader.ReadEndElement();
                                }
                            }
                        }

                        break;

                        case SoapSerializer.DataContractSerializer:
                        {
                            var elementType = parameterInfo.Parameter.ParameterType.GetElementType();
                            if (elementType == null || parameterInfo.Parameter.ParameterType.IsArray)
                            {
                                elementType = parameterInfo.Parameter.ParameterType;
                            }

                            var serializer = new DataContractSerializer(elementType, parameterName, parameterNs);
                            arguments[parameterInfo.Index] = serializer.ReadObject(xmlReader, verifyObjectName: true);
                        }

                        break;

                        default: throw new NotImplementedException();
                        }
                    }
                }
                else if (parameterInfo.Parameter.ParameterType == typeof(HttpContext))
                {
                    arguments[parameterInfo.Index] = httpContext;
                }
                else
                {
                    arguments[parameterInfo.Index] = null;
                }
            }

            foreach (var parameterInfo in operation.OutParameters)
            {
                if (arguments[parameterInfo.Index] != null)
                {
                    // do not overwrite input ref parameters
                    continue;
                }

                if (parameterInfo.Parameter.ParameterType.Name == "Guid&")
                {
                    arguments[parameterInfo.Index] = Guid.Empty;
                }
                else if (parameterInfo.Parameter.ParameterType.Name == "String&" || parameterInfo.Parameter.ParameterType.GetElementType().IsArray)
                {
                    arguments[parameterInfo.Index] = null;
                }
                else
                {
                    var type = parameterInfo.Parameter.ParameterType.GetElementType();
                    arguments[parameterInfo.Index] = Activator.CreateInstance(type);
                }
            }

            return(arguments);
        }
예제 #11
0
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement(_envelopeName, _serviceNamespace);

            if (_outResults != null)
            {
                foreach (var outResult in _outResults)
                {
                    string value;
                    if (outResult.Value is Guid)
                    {
                        value = outResult.Value.ToString();
                    }
                    else if (outResult.Value is bool)
                    {
                        value = outResult.Value.ToString().ToLower();
                    }
                    else if (outResult.Value is string)
                    {
                        value = SecurityElement.Escape(outResult.Value.ToString());
                    }
                    else if (outResult.Value is Enum)
                    {
                        value = outResult.Value.ToString();
                    }
                    else if (outResult.Value == null)
                    {
                        value = null;
                    }
                    else                     //for complex types
                    {
                        using (var ms = new MemoryStream())
                            using (var stream = new BufferedStream(ms))
                            {
                                switch (_serializer)
                                {
                                case SoapSerializer.XmlSerializer:
                                    new XmlSerializer(outResult.Value.GetType()).Serialize(ms, outResult.Value);
                                    break;

                                case SoapSerializer.DataContractSerializer:
                                    new DataContractSerializer(outResult.Value.GetType()).WriteObject(ms, outResult.Value);
                                    break;

                                default: throw new NotImplementedException();
                                }
                                stream.Position = 0;
                                using (var reader = XmlReader.Create(stream))
                                {
                                    reader.MoveToContent();
                                    value = reader.ReadInnerXml();
                                }
                            }
                    }

                    if (value != null)
                    {
                        writer.WriteRaw(string.Format("<{0}>{1}</{0}>", outResult.Key, value));
                    }
                }
            }

            if (_result != null)
            {
                switch (_serializer)
                {
                case SoapSerializer.XmlSerializer:
                {
                    // see https://referencesource.microsoft.com/System.Xml/System/Xml/Serialization/XmlSerializer.cs.html#c97688a6c07294d5
                    var serializer = CachedXmlSerializer.GetXmlSerializer(_result.GetType(), _resultName, _serviceNamespace);
                    lock (serializer)
                        serializer.Serialize(writer, _result);
                }
                break;

                case SoapSerializer.DataContractSerializer:
                {
                    var serializer = new DataContractSerializer(_result.GetType(), _resultName, _serviceNamespace);
                    serializer.WriteObject(writer, _result);
                }
                break;

                default: throw new NotImplementedException();
                }
            }

            writer.WriteEndElement();
        }