/// <summary> /// Deserializes the objects in a WCF message body sent to a particular operation of a WCF service. /// </summary> /// <param name="messageBuffer">A message buffer from which an instance of the traced WCF message can be built</param> /// <param name="contractMethod">The <see cref="MethodBase"/> object of the contract method used to call the trace's operation.</param> /// <remarks> /// <para> /// If the contract parameter is a <see cref="System.IO.Stream">Stream</see> then the returned parameter type /// will be <see cref="System.IO.Stream">Stream</see>, but the value will be a /// <see cref="System.IO.MemoryStream">MemoryStream</see>. /// </para> /// </remarks> /// <returns>Array <see cref="CallParameterInfo"/> objects describing each parameter.</returns> public CallParameterInfo[] DeserializeInputParameters(MessageBuffer messageBuffer, MethodBase contractMethod) { if (contractMethod == null) { throw new ArgumentNullException("contractMethod"); } Type proxyType = contractMethod.DeclaringType; string methodName = contractMethod.Name; if (proxyType == null) { throw new ArgumentException(Messages.DeserializerContractMethodNoDeclaringType); } Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Deserializing buffer for method {0} in type {1}", methodName, proxyType.ToString())); CallParameterInfo[] ans = null; ParameterInfo[] parameters = contractMethod.GetParameters(); string proxyNamespace = this.GetServiceNamespace(proxyType); // TODO: Pluggable: Make choice of deserializer more pluggable, use a factory. if (ProxyManager.IsXmlSerializerMethod(contractMethod)) { if (ProxyManager.IsMessageContractMethod(contractMethod)) { ans = DeserializeXmlSerializerWithBareInputParameter(messageBuffer, proxyNamespace, parameters); } else { ans = DeserializeXmlSerializerInputParameters(messageBuffer, proxyNamespace, parameters); } } else if (ProxyManager.IsMessageContractMethod(contractMethod)) { ans = new CallParameterInfo[] { DeserializeMessageContractInputParameters(messageBuffer, proxyNamespace, parameters[0]) }; } else { IList <Type> serviceKnownTypes = GetServiceKnownTypes(contractMethod.DeclaringType); ans = DeserializeDataContractInputParameters(messageBuffer, proxyNamespace, parameters, serviceKnownTypes); } Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Completed deserializing buffer for method {0} in type {1}", methodName, proxyType.ToString())); return(ans); }
/// <summary> /// Gets the direction of a parameter. /// </summary> /// <param name="p">The parameter to get the direction for.</param> /// <returns>The direction of the parameter.</returns> private static FieldDirection GetDirectionForCustomisationCall(CallParameterInfo p) { Debug.Assert(p.Direction != FieldDirection.Out, "Do not expect to be called for an out parameter"); FieldDirection ans = FieldDirection.In; if (p.ParameterType.IsValueType && p.Value == null) { // This can occur on service-side traces with non stream parameters, the // trace in this case has no data and the deserializer sets its value to null in this case. ans = FieldDirection.Out; } else if (p.ParameterType.IsValueType || p.ParameterType == typeof(string)) { ans = FieldDirection.Ref; } else if (typeof(Stream).IsAssignableFrom(p.ParameterType)) { ans = FieldDirection.Out; } return(ans); }