public object DeserializeInputParameter( System.Xml.XmlDictionaryReader xmlReader, Type parameterType, string parameterName, string parameterNs, ICustomAttributeProvider customAttributeProvider, IEnumerable <Type> knownTypes = null) { // Advance past any whitespace. while (xmlReader.NodeType == System.Xml.XmlNodeType.Whitespace && xmlReader.Read()) { } if (xmlReader.IsStartElement(parameterName, parameterNs)) { xmlReader.MoveToStartElement(parameterName, parameterNs); if (xmlReader.IsStartElement(parameterName, parameterNs)) { switch (_serializer) { case SoapSerializer.XmlSerializer: if (!parameterType.IsArray) { // case [XmlElement("parameter")] int parameter // case [XmlArray("parameter")] int[] parameter return(DeserializeObject(xmlReader, parameterType, parameterName, parameterNs)); } else { // case int[] parameter // case [XmlElement("parameter")] int[] parameter // case [XmlArray("parameter"), XmlArrayItem(ElementName = "item")] int[] parameter return(DeserializeArrayXmlSerializer(xmlReader, parameterType, parameterName, parameterNs, customAttributeProvider)); } case SoapSerializer.DataContractSerializer: return(DeserializeDataContract(xmlReader, parameterType, parameterName, parameterNs, knownTypes)); default: throw new NotImplementedException(); } } } if (parameterType.IsArray) { return(Array.CreateInstance(parameterType.GetElementType(), 0)); } return(null); }
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)); } }
private object[] GetRequestArguments(Message requestMessage, System.Xml.XmlDictionaryReader xmlReader, OperationDescription operation, HttpContext httpContext) { var arguments = new object[operation.AllParameters.Length]; // 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; * ... * }*/ // Find the element for the operation's data if (!operation.IsMessageContractRequest) { xmlReader.ReadStartElement(operation.Name, operation.Contract.Namespace); foreach (var parameterInfo in operation.InParameters) { var parameterType = parameterInfo.Parameter.ParameterType; if (parameterType == typeof(HttpContext)) { arguments[parameterInfo.Index] = httpContext; } else { var argumentValue = _serializerHelper.DeserializeInputParameter(xmlReader, parameterType, parameterInfo.Name, operation.Contract.Namespace, parameterInfo); //fix https://github.com/DigDes/SoapCore/issues/379 (hack, need research) if (argumentValue == null) { argumentValue = _serializerHelper.DeserializeInputParameter(xmlReader, parameterType, parameterInfo.Name, parameterInfo.Namespace, parameterInfo); } arguments[parameterInfo.Index] = argumentValue; } } } else { // MessageContracts are constrained to having one "InParameter". We can do special logic on // for this Debug.Assert(operation.InParameters.Length == 1, "MessageContracts are constrained to having one 'InParameter'"); var parameterInfo = operation.InParameters[0]; var parameterType = parameterInfo.Parameter.ParameterType; var messageContractAttribute = parameterType.GetCustomAttribute <MessageContractAttribute>(); Debug.Assert(messageContractAttribute != null, "operation.IsMessageContractRequest should be false if this is null"); var @namespace = parameterInfo.Namespace ?? operation.Contract.Namespace; if (messageContractAttribute.IsWrapped && !parameterType.GetMembersWithAttribute <MessageHeaderAttribute>().Any()) { // It's wrapped so we treat it like normal! arguments[parameterInfo.Index] = _serializerHelper.DeserializeInputParameter(xmlReader, parameterInfo.Parameter.ParameterType, parameterInfo.Name, @namespace, parameterInfo); } else { var messageHeadersMembers = parameterType.GetPropertyOrFieldMembers().Where(x => x.GetCustomAttribute <MessageHeaderAttribute>() != null).ToArray(); var wrapperObject = Activator.CreateInstance(parameterInfo.Parameter.ParameterType); for (var i = 0; i < requestMessage.Headers.Count; i++) { var header = requestMessage.Headers[i]; var member = messageHeadersMembers.FirstOrDefault(x => x.Name == header.Name); if (member != null) { var messageHeaderAttribute = member.GetCustomAttribute <MessageHeaderAttribute>(); var reader = requestMessage.Headers.GetReaderAtHeader(i); var value = _serializerHelper.DeserializeInputParameter(reader, member.GetPropertyOrFieldType(), messageHeaderAttribute.Name ?? member.Name, messageHeaderAttribute.Namespace ?? @namespace); member.SetValueToPropertyOrField(wrapperObject, value); } } // This object isn't a wrapper element, so we will hunt for the nested message body // member inside of it var messageBodyMembers = parameterType.GetPropertyOrFieldMembers().Where(x => x.GetCustomAttribute <MessageBodyMemberAttribute>() != null).Select(mi => new { Member = mi, MessageBodyMemberAttribute = mi.GetCustomAttribute <MessageBodyMemberAttribute>() }).OrderBy(x => x.MessageBodyMemberAttribute.Order); if (messageContractAttribute.IsWrapped) { xmlReader.Read(); } foreach (var messageBodyMember in messageBodyMembers) { var messageBodyMemberAttribute = messageBodyMember.MessageBodyMemberAttribute; var messageBodyMemberInfo = messageBodyMember.Member; var innerParameterName = messageBodyMemberAttribute.Name ?? messageBodyMemberInfo.Name; var innerParameterNs = messageBodyMemberAttribute.Namespace ?? @namespace; var innerParameterType = messageBodyMemberInfo.GetPropertyOrFieldType(); //xmlReader.MoveToStartElement(innerParameterName, innerParameterNs); var innerParameter = _serializerHelper.DeserializeInputParameter(xmlReader, innerParameterType, innerParameterName, innerParameterNs, parameterInfo); messageBodyMemberInfo.SetValueToPropertyOrField(wrapperObject, innerParameter); } arguments[parameterInfo.Index] = wrapperObject; } } 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); }