/// <summary> /// Build a message reply. /// </summary> /// <param name="request">Request message.</param> /// <param name="body">Reply message's body.</param> public static AmfGenericMessage BuildMessageReply(AmfGenericMessage request, object body) { var replyHeaders = new Dictionary<string, AmfHeader>(); var replyMessage = new AmfMessage { Target = CreateResultReplyTarget(request.AmfMessage), Response = string.Empty, Data = body }; return new AmfGenericMessage(replyHeaders, replyMessage); }
public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { //An internal server error occured if (OperationContext.Current == null) return; //An AMF operation if (OperationContext.Current.IncomingMessageProperties.ContainsKey(MessagingHeaders.InvokerMessageBody)) { var replyHeaders = new Dictionary<string, AmfHeader>(); var replyMessage = new AmfMessage { Response = string.Empty }; var requestMessage = (AmfMessage)OperationContext.Current.IncomingMessageProperties[MessagingHeaders.InvokerMessageBody]; //An RPC operation if (OperationContext.Current.IncomingMessageProperties.ContainsKey(MessagingHeaders.RemotingMessage)) { var rpcMessage = (RemotingMessage)OperationContext.Current.IncomingMessageProperties[MessagingHeaders.RemotingMessage]; var acknowledge = AmfOperationUtil.BuildErrorMessage(rpcMessage); if (acknowledge.Headers == null) acknowledge.Headers = new Dictionary<string, object>(); if (error is AmfOperationNotFoundException) acknowledge.Headers[AmfMessageHeader.StatusCode] = (int)HttpStatusCode.NotFound; else acknowledge.Headers[AmfMessageHeader.StatusCode] = (int)HttpStatusCode.BadRequest; acknowledge.FaultCode = ErrorMessageFaultCode.DeliveryInDoubt; acknowledge.FaultString = error.Message; if (_capabilities.ExceptionDetailInFaults) { acknowledge.FaultDetail = error.StackTrace; } //Get FaultException's detail object, if any if(error is FaultException) { var type = error.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(FaultException<>))) { acknowledge.ExtendedData = type.GetProperty("Detail").GetValue(error, null); } } replyMessage.Target = AmfOperationUtil.CreateStatusReplyTarget(requestMessage); replyMessage.Data = acknowledge; } fault = new AmfGenericMessage(replyHeaders, replyMessage); } }
/// <summary> /// Constructor. /// </summary> /// <param name="headers">AMF headers.</param> /// <param name="message">AMF message.</param> public AmfGenericMessage(IDictionary<string, AmfHeader> headers, AmfMessage message) : base(headers) { if (message == null) throw new ArgumentNullException("message"); _amfMessage = message; }
/// <summary> /// Create a status message's reply target. /// </summary> /// <param name="requestMessage">Request message.</param> public static string CreateStatusReplyTarget(AmfMessage requestMessage) { return string.Format(OperationFaultTarget, requestMessage.Response ?? string.Empty); }
/// <summary> /// Serializes a reply message from a specified message version, array of parameters, and a return value. /// </summary> /// <param name="messageVersion">The SOAP message version.</param> /// <param name="parameters">The out parameters.</param> /// <param name="result">The return value.</param> /// <returns>The serialized reply message.</returns> public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { //An AMF operation if (OperationContext.Current.IncomingMessageProperties.ContainsKey(MessagingHeaders.InvokerMessageBody)) { var requestMessage = (AmfMessage)OperationContext.Current.IncomingMessageProperties[MessagingHeaders.InvokerMessageBody]; //An RPC operation if (OperationContext.Current.IncomingMessageProperties.ContainsKey(MessagingHeaders.RemotingMessage)) { var rpcMessage = (RemotingMessage)OperationContext.Current.IncomingMessageProperties[MessagingHeaders.RemotingMessage]; var acknowledge = AmfOperationUtil.BuildAcknowledgeMessage(rpcMessage); acknowledge.Body = result; result = acknowledge; } var replyHeaders = new Dictionary<string, AmfHeader>(); var replyMessage = new AmfMessage { Data = result, Target = AmfOperationUtil.CreateResultReplyTarget(requestMessage), Response = string.Empty }; return new AmfGenericMessage(replyHeaders, replyMessage); } throw new OperationCanceledException(Errors.AmfGenericOperationFormatter_SerializeReply_InvalidOperation); }
/// <summary> /// Deserialize an AMFX packet. /// </summary> /// <exception cref="SerializationException">Error during deserialization.</exception> private static object DeserializePacket(XmlReader reader, SerializationContext context) { if (reader == null) throw new ArgumentNullException("reader"); if (context == null) throw new ArgumentNullException("context"); var packet = new AmfPacket(); while (reader.Read()) { if (reader.NodeType != XmlNodeType.Element) continue; #region Read packet header if (reader.Name == AmfxContent.PacketHeader) { var header = new AmfHeader { Name = reader.GetAttribute(AmfxContent.PacketHeaderName), MustUnderstand = (reader.GetAttribute(AmfxContent.PacketHeaderMustUnderstand) == AmfxContent.True) }; while (reader.Read()) { //Skip until header content is found, if any if (reader.NodeType != XmlNodeType.Element || reader.Name == AmfxContent.PacketHeader) continue; header.Data = Deserialize(reader, context); break; } packet.Headers[header.Name] = header; continue; } #endregion #region Read packet body if (reader.Name == AmfxContent.PacketBody) { var message = new AmfMessage { Target = reader.GetAttribute(AmfxContent.PacketBodyTarget), Response = reader.GetAttribute(AmfxContent.PacketBodyResponse) }; while (reader.Read()) { //Skip until body content is found, if any if (reader.NodeType != XmlNodeType.Element || reader.Name == AmfxContent.PacketBody) continue; message.Data = Deserialize(reader, context); break; } packet.Messages.Add(message); continue; } #endregion } return packet; }