private void CheckAndMakeMetaDataRequest(Message originalMessage, TimeSpan timeout) { var action = originalMessage.Headers.Action; var contractInfo = ContractInfo.FromAction(action); var serviceContract = TypeFinder.FindServiceContract(contractInfo.ServiceContractName); var paramTypes = TypeFinder.GetContractParamTypes(serviceContract, contractInfo.OperationContractName, contractInfo.Action); var store = ObjectBuilder.GetModelStore(); var metaDataRequired = paramTypes.Any(paramType => store.GetModel(paramType.Type, ModeType.Wcf) == null); if (!metaDataRequired) { return; } var metadataRequestMessage = GetMetaDataRequestMessage(action); var metaDataReply = _innerChannel.Request(metadataRequestMessage); if (metaDataReply == null) { throw new FaultException( string.Format( "The service at {0} could not be contacted to get the necessary metadata, make sure the server is available.", RemoteAddress.Uri.ToString() )); } var headers = metaDataReply.Headers; var serializer = ObjectBuilder.GetSerializer(); var modelProvider = ObjectBuilder.GetModelProvider(); foreach (var messageHeader in headers) { if (messageHeader.Name.StartsWith(Constants.MetaDataHeaderKeySuffix)) { var contractNamespace = messageHeader.Name.Replace(Constants.MetaDataHeaderKeySuffix, string.Empty); var contractType = TypeFinder.FindDataContract(contractNamespace, contractInfo.ServiceContractName, contractInfo.Action); var contractMetaDataString = headers.GetHeader <string>(messageHeader.Name, messageHeader.Namespace); var contractMeta = BinaryConverter.FromString(contractMetaDataString); var metaData = serializer.Deserialize <TypeMetaData>(contractMeta, ModeType.Wcf); modelProvider.CreateModelInfo(contractType, metaData, ModeType.Wcf); } } }