/// <summary> /// Initializes a new instance of the BrokerResponse class /// </summary> /// <param name="typedMessageConverter">Converts response message to its type</param> /// <param name="messageBuffer">Response message's buffer</param> /// <param name="faultCollection">indicating the fault collection</param> /// <param name="requestMessageId">indicating the request message id</param> internal BrokerResponse(TypedMessageConverter typedMessageConverter, MessageBuffer messageBuffer, FaultDescriptionCollection faultCollection, UniqueId requestMessageId) : this(requestMessageId) { this.typedMessageConverter = typedMessageConverter; this.messageBuffer = messageBuffer; this.faultCollection = faultCollection; }
private static void AddFaultProtectionRequirements(FaultDescriptionCollection faults, ChannelProtectionRequirements requirements, ProtectionLevel defaultProtectionLevel, bool addToIncoming) { if (faults == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("faults")); } if (requirements == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("requirements")); } foreach (FaultDescription description in faults) { MessagePartSpecification parts = new MessagePartSpecification(); MessagePartSpecification specification2 = new MessagePartSpecification(); ProtectionLevel level = description.HasProtectionLevel ? description.ProtectionLevel : defaultProtectionLevel; if (level != ProtectionLevel.None) { parts.IsBodyIncluded = true; if (level == ProtectionLevel.EncryptAndSign) { specification2.IsBodyIncluded = true; } } if (addToIncoming) { requirements.IncomingSignatureParts.AddParts(parts, description.Action); requirements.IncomingEncryptionParts.AddParts(specification2, description.Action); } else { requirements.OutgoingSignatureParts.AddParts(parts, description.Action); requirements.OutgoingEncryptionParts.AddParts(specification2, description.Action); } } }
private object GetFaultDetail(MethodInfo method, FaultDescriptionCollection faults, Exception error) { object faultDetail = null; if (m_convert != null) { faultDetail = m_convert.ConvertExceptionToFaultDetail(error); } if (faultDetail == null && method != null) { MapExceptionToFaultAttribute[] mappers = (MapExceptionToFaultAttribute[]) method.GetCustomAttributes(typeof(MapExceptionToFaultAttribute), true); foreach (MapExceptionToFaultAttribute mapAttribute in mappers) { if (mapAttribute.ExceptionType == error.GetType()) { faultDetail = mapAttribute.GetFaultDetailForException(error); if (faultDetail != null) { break; } } } } if (faultDetail != null && m_attrib.EnforceFaultContract && !faults.Any(f => f.DetailType == faultDetail.GetType())) { faultDetail = null; } if (faultDetail == null) { foreach (FaultDescription faultDesc in faults) { if (faultDesc.DetailType == error.GetType()) { faultDetail = error; break; } } } return(faultDetail); }
private static void AddFaultProtectionRequirements(FaultDescriptionCollection faults, ChannelProtectionRequirements requirements, ProtectionLevel defaultProtectionLevel, bool addToIncoming) { if (faults == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(faults)); } if (requirements == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(requirements)); } foreach (FaultDescription fault in faults) { var signedParts = new MessagePartSpecification(); var encryptedParts = new MessagePartSpecification(); ProtectionLevel p = defaultProtectionLevel; // FaultDescription.HasProtectionLevel currently is always false //ProtectionLevel p = fault.HasProtectionLevel ? fault.ProtectionLevel : defaultProtectionLevel; if (p != ProtectionLevel.None) { signedParts.IsBodyIncluded = true; if (p == ProtectionLevel.EncryptAndSign) { encryptedParts.IsBodyIncluded = true; } } if (addToIncoming) { requirements.IncomingSignatureParts.AddParts(signedParts, fault.Action); requirements.IncomingEncryptionParts.AddParts(encryptedParts, fault.Action); } else { requirements.OutgoingSignatureParts.AddParts(signedParts, fault.Action); requirements.OutgoingEncryptionParts.AddParts(encryptedParts, fault.Action); } } }
public OperationDescription(string name, ContractDescription declaringContract) { if (name == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name"); } if (name.Length == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("name", SR.SFxOperationDescriptionNameCannotBeEmpty)); } _name = new XmlName(name, true /*isEncoded*/); if (declaringContract == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("declaringContract"); } _declaringContract = declaringContract; _isInitiating = true; _faults = new FaultDescriptionCollection(); _messages = new MessageDescriptionCollection(); _behaviors = new KeyedByTypeCollection<IOperationBehavior>(); _knownTypes = new Collection<Type>(); }
/// <summary> /// Dynamically creates objects needed to deserialize a response message. Keeps last deserializer since its likely it will be reused /// </summary> /// <param name="actionFromResponse">indicating the action from the response header</param> /// <param name="replyAction">indicating the reply action</param> /// <param name="messageBuffer">indicating the message buffer</param> /// <param name="relatesTo">indicating the relatesTo header</param> /// <returns>returns the created instance of BrokerResponse class</returns> private BrokerResponse <TMessage> CreateResponse(string actionFromResponse, string replyAction, MessageBuffer messageBuffer, UniqueId relatesTo) { TypedMessageConverter typedMessageConverter = null; FaultDescriptionCollection faultCollection = null; Type responseType = null; // If the actionFromResponse is empty, this is a broker fault. BrokerResponse can handle this with no app service specific information if (!String.IsNullOrEmpty(actionFromResponse)) { // Check if we already have a response message converter & fault collection for this action. If not get it from the BrokerClient if (this.typedMessageConverter != null && this.replyAction == replyAction) { typedMessageConverter = this.typedMessageConverter; faultCollection = this.faultCollection; responseType = this.responseType; } else { string errorMessage = null; // Get the deserialization objects from the BrokerClient if (!this.brokerClient.GetResponseMessageInfo(ref actionFromResponse, ref replyAction, ref responseType, out typedMessageConverter, out faultCollection, out errorMessage)) { throw new InvalidOperationException(errorMessage); } this.action = actionFromResponse; this.replyAction = replyAction; this.typedMessageConverter = typedMessageConverter; this.faultCollection = faultCollection; this.responseType = responseType; } } return(new BrokerResponse <TMessage>(this.typedMessageConverter, messageBuffer, this.faultCollection, relatesTo)); }
// Methods public OperationDescription(string name, ContractDescription declaringContract) { this.validateRpcWrapperName = true; if (name == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name"); } if (name.Length == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("name", SR.GetString("SFxOperationDescriptionNameCannotBeEmpty"))); } this.name = new XmlName(name, true); if (declaringContract == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("declaringContract"); } this.declaringContract = declaringContract; this.isInitiating = true; this.isTerminating = false; this.faults = new FaultDescriptionCollection(); this.messages = new MessageDescriptionCollection(); this.behaviors = new KeyedByTypeCollection<IOperationBehavior>(); this.knownTypes = new Collection<Type>(); }
private static void AddFaultProtectionRequirements(FaultDescriptionCollection faults, ChannelProtectionRequirements requirements, ProtectionLevel defaultProtectionLevel, bool addToIncoming) { if (faults == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("faults")); if (requirements == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("requirements")); foreach (FaultDescription fault in faults) { MessagePartSpecification signedParts = new MessagePartSpecification(); MessagePartSpecification encryptedParts = new MessagePartSpecification(); ProtectionLevel p = fault.HasProtectionLevel ? fault.ProtectionLevel : defaultProtectionLevel; if (p != ProtectionLevel.None) { signedParts.IsBodyIncluded = true; if (p == ProtectionLevel.EncryptAndSign) { encryptedParts.IsBodyIncluded = true; } } if (addToIncoming) { requirements.IncomingSignatureParts.AddParts(signedParts, fault.Action); requirements.IncomingEncryptionParts.AddParts(encryptedParts, fault.Action); } else { requirements.OutgoingSignatureParts.AddParts(signedParts, fault.Action); requirements.OutgoingEncryptionParts.AddParts(encryptedParts, fault.Action); } } }
/// <summary> /// Returns the TypedMessageConverter and operation faults for the specified action and reply action /// </summary> /// <returns></returns> internal bool GetResponseMessageInfo(ref string action, ref string replyAction, ref Type responseType, out TypedMessageConverter typedMessageConverter, out FaultDescriptionCollection faultCollection, out string errorMessage) { int operationIndex = 0; int operationMatchIndex = -1; int actionMatchIndex = -1; int replyActionMatchIndex = -1; int operationQueryID = -1; typedMessageConverter = null; faultCollection = null; errorMessage = "Unexpected error"; // If caller explicitly passes action and replyAction to GetResponses or AddResponseHandler, look for both if (!String.IsNullOrEmpty(action) && !String.IsNullOrEmpty(replyAction)) { operationQueryID = 0; } // If the caller passes just a response message type to GetResponses or AddResponseHandler, look for response type else if (responseType != null) { operationQueryID = 1; } // If the caller is using a typeless GetResponses or AddResponseHander, look for action else if (!String.IsNullOrEmpty(action)) { operationQueryID = 2; } // Otherwise we have unexecpted input else { return(false); } // Loop through all the message descriptions of all the operations and look for matches foreach (OperationDescription operationDescription in this.operations) { bool actionMatch = false; bool replyActionMatch = false; int actionIndex = -1; int replyActionIndex = -1; int messageDescriptonIndex = 0; foreach (MessageDescription messageDescription in operationDescription.Messages) { if (messageDescription.Direction == MessageDirection.Input) { if (messageDescription.Action == action) { actionMatch = true; } actionIndex = messageDescriptonIndex; } else if (messageDescription.Direction == MessageDirection.Output) { if (messageDescription.Action == replyAction || messageDescription.MessageType == responseType) { replyActionMatch = true; } replyActionIndex = messageDescriptonIndex; } messageDescriptonIndex++; } // If we are looking for an exact match AND found matching action and reply actions // OR we are looking for a replyAction match AND found a matching reply action // OR we are looking for a action match AND found a matching action if ((operationQueryID == 0 && actionMatch && replyActionMatch) || (operationQueryID == 1 && replyActionMatch) || (operationQueryID == 2 && actionMatch)) { // If a previous operation was already matched, return ambiguous error if (operationMatchIndex != -1) { errorMessage = SR.AmbiguousOperation; return(false); } // Else save the operation and its reply message description operationMatchIndex = operationIndex; actionMatchIndex = actionIndex; replyActionMatchIndex = replyActionIndex; } operationIndex++; } // If no matching operation was found, return operation not found if (operationMatchIndex == -1) { errorMessage = "Operation not found for specified actions"; return(false); } // Create typedMessageCoverter and get fault collection OperationDescription operation = this.operations[operationMatchIndex]; MessageDescription requestMessageDescription = operation.Messages[actionMatchIndex]; MessageDescription replyMessageDescription = operation.Messages[replyActionMatchIndex]; typedMessageConverter = TypedMessageConverter.Create(replyMessageDescription.MessageType, replyMessageDescription.Action); action = requestMessageDescription.Action; replyAction = replyMessageDescription.Action; responseType = replyMessageDescription.MessageType; faultCollection = operation.Faults; Debug.Assert(responseType != typeof(object) ? responseType == replyMessageDescription.MessageType : true, "Unexpected action/response type match!"); return(true); }
/// <summary> /// Gets the fault detail. /// </summary> /// <param name="method">The method.</param> /// <param name="faults">The faults.</param> /// <param name="error">The error.</param> /// <returns></returns> private object GetFaultDetail(MethodInfo method, FaultDescriptionCollection faults, Exception error) { object faultDetail = null; if (exceptionMapper != null) { faultDetail = exceptionMapper.MapToFault(error); } if (faultDetail == null && method != null) { ExceptionMappingAttribute[] mappers = (ExceptionMappingAttribute[]) method.GetCustomAttributes(typeof(ExceptionMappingAttribute), true); foreach (ExceptionMappingAttribute mapAttribute in mappers) { if (mapAttribute.ExceptionType == error.GetType()) { faultDetail = mapAttribute.GetFaultDetailForException(error); if (faultDetail != null) { break; } } } } if (faultDetail != null && handlingAttribute.EnforceFaultContract && !faults.Any(f => f.DetailType == faultDetail.GetType())) { faultDetail = null; } if (faultDetail == null) { foreach (FaultDescription faultDesc in faults) { if (faultDesc.DetailType == error.GetType()) { faultDetail = error; break; } } } return faultDetail; }