/// <summary> /// Prepares a reply /// </summary> /// <param name="request">The request context to prepare</param> /// <param name="reply">The reply to prepare</param> /// <returns>True if channel is open and prepared reply should be sent; otherwise false.</returns> bool PrepareReply(RequestContext request, Message reply) { // Ensure we only reply once (we may hit the same error multiple times) if (_replied == request) { return(false); } _replied = request; bool canSendReply = true; Message requestMessage = null; try { requestMessage = request.RequestMessage; } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } // swallow it } if (!object.ReferenceEquals(requestMessage, null)) { UniqueId requestID = null; try { requestID = requestMessage.Headers.MessageId; } catch (MessageHeaderException) { // swallow it - we don't need to correlate the reply if the MessageId header is bad } if (!object.ReferenceEquals(requestID, null) && !_isManualAddressing) { RequestReplyCorrelator.PrepareReply(reply, requestID); } if (!_hasSession && !_isManualAddressing) { try { canSendReply = RequestReplyCorrelator.AddressReply(reply, requestMessage); } catch (MessageHeaderException) { // swallow it - we don't need to address the reply if the FaultTo header is bad } } } // ObjectDisposeException can happen // if the channel is closed in a different // thread. 99% this check will avoid false // exceptions. return(IsOpen && canSendReply); }
bool PrepareAndAddressReply(ref MessageRpc rpc) { bool canSendReply = true; if (!manualAddressing) { if (!object.ReferenceEquals(rpc.RequestID, null)) { RequestReplyCorrelator.PrepareReply(rpc.Reply, rpc.RequestID); } if (!rpc.Channel.HasSession) { canSendReply = RequestReplyCorrelator.AddressReply(rpc.Reply, rpc.ReplyToInfo); } } AddMessageProperties(rpc.Reply, rpc.OperationContext, rpc.Channel); //if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled && rpc.EventTraceActivity != null) //{ // rpc.Reply.Properties[EventTraceActivity.Name] = rpc.EventTraceActivity; //} return(canSendReply); }
protected void OnReceive(Message message) { DebugTrace.TraceEnter(this, "OnReceive"); if ((message != null) && !this.tokenResolver.FaultInSupportingToken(message)) { if (DebugTrace.Verbose) { DebugTrace.Trace(TraceLevel.Verbose, "Failed to fault in SCT for supporting token signature"); } Fault invalidParameters = Faults.Version(this.protocolVersion).InvalidParameters; if (message.Headers.MessageId != null) { if (DebugTrace.Verbose) { DebugTrace.Trace(TraceLevel.Verbose, "Attempting to send {0} fault", invalidParameters.Code.Name); } Message reply = Library.CreateFaultMessage(message.Headers.MessageId, message.Version, invalidParameters); RequestReplyCorrelator.AddressReply(reply, new RequestReplyCorrelator.ReplyToInfo(message)); SendSecurityHeader header = SupportingTokenChannel <TChannel> .SecurityStandardsManager.CreateSendSecurityHeader(reply, string.Empty, true, false, SecurityAlgorithmSuite.Default, MessageDirection.Output); header.RequireMessageProtection = false; header.AddTimestamp(SecurityProtocolFactory.defaultTimestampValidityDuration); reply = header.SetupExecution(); this.TrySendFaultReply(reply); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(Microsoft.Transactions.SR.GetString("SupportingTokenSignatureExpected"))); } DebugTrace.TraceLeave(this, "OnReceive"); }