/// <summary> /// Deserializes message contract input parameters. /// </summary> /// <param name="messageBuffer">The buffer containing the message to be deserialized.</param> /// <param name="proxyNamespace">The namespace of the proxy.</param> /// <param name="parameter">The parameter to be deserialized.</param> /// <returns>Deserialized input parameter.</returns> private static CallParameterInfo DeserializeMessageContractInputParameters(MessageBuffer messageBuffer, string proxyNamespace, ParameterInfo parameter) { Message message = messageBuffer.CreateMessage(); TypedMessageConverter converter = TypedMessageConverter.Create(parameter.ParameterType, message.Headers.Action, proxyNamespace); object o; try { o = converter.FromMessage(message); } catch (System.Xml.XmlException) { o = Activator.CreateInstance(parameter.ParameterType); } catch (System.Runtime.Serialization.SerializationException) { o = Activator.CreateInstance(parameter.ParameterType); } catch (CommunicationException) { o = Activator.CreateInstance(parameter.ParameterType); } return(new CallParameterInfo(parameter.Name, parameter.ParameterType, FieldDirection.In, o)); }
static void Main(string[] args) { string action = null; XmlReader bodyReader = XmlReader.Create(new StringReader("<Example xmlns=\"http://tempuri.org/\"><Gold>109</Gold><Message>StackOverflow</Message></Example>")); Message msg = Message.CreateMessage(MessageVersion.Default, action, bodyReader); TypedMessageConverter converter = TypedMessageConverter.Create(typeof(Example), "http://tempuri.org/IFoo/BarOperation"); Example example = (Example)converter.FromMessage(msg); }
public static void Main() { TypedMessageConverter c = TypedMessageConverter.Create( typeof(Test), "http://tempuri.org/MyTest"); Message msg = c.ToMessage(new Test()); MessageBuffer mb = msg.CreateBufferedCopy(10); using (XmlWriter w = XmlWriter.Create(Console.Out)) { mb.CreateMessage().WriteMessage(w); } Test t = (Test)c.FromMessage(mb.CreateMessage()); }
public void StandardRoundtrip() { TypedMessageConverter c = TypedMessageConverter.Create( typeof(Test1), "http://tempuri.org/MyTest"); Test1 t1 = new Test1(); t1.echo.msg = "test"; t1.body2 = "testtest"; Message msg = c.ToMessage(t1); Test1 t2 = (Test1)c.FromMessage(msg); Assert.AreEqual("test", t2.echo.msg, "#01"); Assert.AreEqual("testtest", t2.body2, "#02"); }
/// <summary> /// Deserializes bare input parameters using the <see cref="XmlSerializer"/>. /// </summary> /// <param name="messageBuffer">The buffer containing the message to be deserialized.</param> /// <param name="proxyNamespace">The namespace of the proxy.</param> /// <param name="parameters">The parameters to be deserialized.</param> /// <returns>Deserialized input parameters.</returns> private static CallParameterInfo[] DeserializeXmlSerializerWithBareInputParameter(MessageBuffer messageBuffer, string proxyNamespace, ParameterInfo[] parameters) { Debug.Assert(parameters.Length == 1, "Expect only one parameter for bare XmlSerializer parameter"); List <CallParameterInfo> ans = new List <CallParameterInfo>(); Message message = messageBuffer.CreateMessage(); foreach (ParameterInfo parameter in parameters) { TypedMessageConverter converter = TypedMessageConverter.Create(parameter.ParameterType, message.Headers.Action, proxyNamespace, new XmlSerializerFormatAttribute()); object o = converter.FromMessage(message); ans.Add(new CallParameterInfo(parameter.Name, parameter.ParameterType, FieldDirection.In, o)); } return(ans.ToArray()); }
public void StandardRoundtrip2() { TypedMessageConverter c = TypedMessageConverter.Create( typeof(Test2), "http://tempuri.org/MyTest"); var t1 = new Test2(); t1.Body = new Echo() { msg = "test" }; var uid = Guid.NewGuid(); t1.Id = uid; Message msg = c.ToMessage(t1); var t2 = (Test2)c.FromMessage(msg); Assert.AreEqual("test", t2.Body.msg, "#01"); Assert.AreEqual(uid, t2.Id, "#02"); }
public void XmlSerializerdWithXmlAttribute() { TypedMessageConverter c = TypedMessageConverter.Create( typeof(Test3), "http://tempuri.org/MyTest", new XmlSerializerFormatAttribute()); string xmlMessage = @"<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope' xmlns:a='http://www.w3.org/2005/08/addressing'> <s:Header><a:Action s:mustUnderstand='1'>http://tempuri.org/MyTest</a:Action></s:Header> <s:Body xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <test xmlns='urn:foo'> <Id>OneID</Id> <Element> <Prop1 xmlns='urn:bar'>foo</Prop1> <Prop2 xmlns='urn:bar'>2</Prop2> </Element> <Element> <Prop1 xmlns='urn:bar'>bar</Prop1> <Prop2 xmlns='urn:bar'>3</Prop2> </Element> </test> </s:Body> </s:Envelope>" ; byte[] buffer = Encoding.UTF8.GetBytes(xmlMessage); using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(buffer, XmlDictionaryReaderQuotas.Max)) { Message messagedisk = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap12); Test3 obj = c.FromMessage(messagedisk) as Test3; Assert.IsNotNull(obj); Assert.AreEqual("OneID", obj.Id); Assert.IsNotNull(obj.ArrayOfElement); Assert.AreEqual(2, obj.ArrayOfElement.Length); Assert.AreEqual("foo", obj.ArrayOfElement[0].Prop1); Assert.AreEqual(3, obj.ArrayOfElement[1].Prop2); } }
/// <summary> /// Receives response messages from broker's response service /// </summary> /// <param name="message">Response message</param> public void SendResponse(Message message) { try { int currentResponseCount = 0; // Reset the heartbeat since operation just succeeded this.session.ResetHeartbeat(); // Reset timeout timer since a response was received if (this.responseHandlerTimeoutTimer != null) { this.responseHandlerTimeoutTimer.Change(this.responseHanderTimeout, 0); } // Bug #15946: handling client side exception thrown from WebResponseHandler(when talking to rest service) if (string.Equals(message.Headers.Action, Constant.WebAPI_ClientSideException, StringComparison.Ordinal)) { Exception e = message.Properties[Constant.WebAPI_ClientSideException] as Exception; this.InvokeCallback(new BrokerResponse <TMessage>(e, message.Headers.RelatesTo)); return; } // TODO: Consider whether user callback should get an EOM message if (!Utility.IsEOM(message)) { // If the handler is closed, timed out, closed or broker heartbeat signaled, dont forward any more requests to the user. // NOTE: If some responses already slipped through its OK because we prefer that over adding a lock here if (this.shuttingDown) { return; } // Create a BrokerResponse object wrapper for the message object. A copy of the message must be created MessageBuffer messageBuffer = null; try { messageBuffer = message.CreateBufferedCopy(Constant.MaxBufferSize); } catch (Exception e) { Utility.LogError("AsyncResponseCallback.SendResponse received exception - {0}", e); this.InvokeCallback(new BrokerResponse <TMessage>(e, message.Headers.RelatesTo)); return; } BrokerResponse <TMessage> brokerResponse = this.CreateResponse(BrokerClientBase.GetActionFromResponseMessage(message), !message.IsFault ? message.Headers.Action : String.Empty, messageBuffer, message.Headers.RelatesTo == null ? SoaHelper.GetMessageId(message) : message.Headers.RelatesTo); BrokerResponse <TMessage> lastResponse = null; if (this.ignoreIsLastResponseProperty) { lastResponse = brokerResponse; } else { // Atomically swap out the last response. lastResponse = Interlocked.Exchange <BrokerResponse <TMessage> >(ref this.lastBrokerResponse, brokerResponse); } // If there was a previous last response if (lastResponse != null) { // Send it to the callback this.InvokeCallback(lastResponse); // Increment response count currentResponseCount = Interlocked.Increment(ref this.currentResponseCount); } // If the caller wants all messages at once, do so. // Else we always request ResponseWindowSize * 2 messages. If we get to // the end of a window, request another if (this.responseWindowSize != Constant.GetResponse_All && currentResponseCount != 0 && (currentResponseCount + 1) % this.responseWindowSize == 0) { // Call async version and block on completion in order to workaround System.Net.Socket bug #750028 try { SessionBase.TraceSource.TraceInformation("GetResponse : currentResponseCount {0} : clientId {1}", currentResponseCount, this.clientId); this.responseService.GetResponses( this.action, this.callbackManagerId, GetResponsePosition.Current, this.responseWindowSize, this.clientId); } catch (FaultException <SessionFault> e) { throw Utility.TranslateFaultException(e); } } } // If this is a client purged fault, return that exception in a BrokerResponse else { TypedMessageConverter endOfResponsesConverter = TypedMessageConverter.Create(typeof(EndOfResponses), Constant.EndOfMessageAction); EndOfResponses endOfResponses = (EndOfResponses)endOfResponsesConverter.FromMessage(message); switch (endOfResponses.Reason) { case EndOfResponsesReason.ClientPurged: this.InvokeCallback(new BrokerResponse <TMessage>(SessionBase.ClientPurgedException, new UniqueId(Guid.Empty))); break; case EndOfResponsesReason.ClientTimeout: this.InvokeCallback(new BrokerResponse <TMessage>(SessionBase.ClientTimeoutException, new UniqueId(Guid.Empty))); break; default: // Save how many responses are expected (minus 1 for the last response) System.Diagnostics.Debug.Assert(endOfResponses.Count > 0, "Response count should also be positive number"); this.expectedResponseCount = endOfResponses.Count - 1; break; } } if (!this.ignoreIsLastResponseProperty) { // Check to see if we receive the EOM message and all the responses. // If so pass last response to callback marked as such. Also make // sure this isnt called again with a lock. if (this.expectedResponseCount == this.currentResponseCount) { lock (this.lastResponseLock) { if (this.expectedResponseCount == this.currentResponseCount) { // Mark the response as the last one this.lastBrokerResponse.isLastResponse = true; // Send last response to callback. Note since currentResponseCount // is incremented after responses are sent to the callback, the // callback will not be processing any other responses at this time. this.InvokeCallback(this.lastBrokerResponse); this.expectedResponseCount = -1; } } } } } catch (Exception e) { // Log and eat unhandled user exceptions from their calback Utility.LogError("Unhandled exception processing response - {0}", e); } }
protected override object GetMessageObject(Message message) { TypedMessageConverter converter = getCachedConverter(message.Headers.Action); return(converter.FromMessage(message)); }
/// <summary> /// Parsing response stream and fetch response mesage from it /// </summary> private void ParsingResponseThreadProc() { try { using (WebResponse response = this.request.GetResponse()) using (Stream responseStream = response.GetResponseStream()) using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(responseStream, DefaultReaderQuotas)) { reader.ReadStartElement(); // this.disposeFlag is marked volatile so that the compiler // won't cache the value here while (!this.disposeFlag) { // In case of network failure and hang, // this call should eventually timed out Message m = ReadMessage(reader); if (m == null) { return; } if (m.Headers.Action.Equals(BrokerInstanceUnavailable.Action, StringComparison.InvariantCultureIgnoreCase)) { TypedMessageConverter converter = TypedMessageConverter.Create(typeof(BrokerInstanceUnavailable), BrokerInstanceUnavailable.Action); BrokerInstanceUnavailable biu = (BrokerInstanceUnavailable)converter.FromMessage(m); SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[WebResponseHandler] Received broker unavailable message, BrokerLauncherEpr = {0}, BrokerNodeDown= {1}", biu.BrokerLauncherEpr, biu.IsBrokerNodeDown); this.callback.SendBrokerDownSignal(biu.IsBrokerNodeDown); break; } else { SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "[WebResponseHandler] Received response message: MessageId = {0}, Action = {1}", m.Headers.MessageId, m.Headers.Action); this.callback.SendResponse(m); } } } } catch (Exception e) { SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[WebBrokerFrontendForGetResponse] Failed to read response from the response stream: {0}", e); if (this.disposeFlag) { // If it has already been disposed, do not // pass the exception to the enumerator return; } Exception exceptionToThrow = e; WebException we = e as WebException; if (we != null) { exceptionToThrow = WebAPIUtility.ConvertWebException(we); FaultException <SessionFault> faultException = exceptionToThrow as FaultException <SessionFault>; if (faultException != null) { exceptionToThrow = Utility.TranslateFaultException(faultException); } } //Bug #15946: throw exception instead of signaling broker down. //Note: To pass the exception to AsyncResponseCallback, wrap it as a response message with special action field. Message exceptionMessage = Message.CreateMessage(MessageVersion.Default, Constant.WebAPI_ClientSideException); exceptionMessage.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData)); exceptionMessage.Properties.Add(Constant.WebAPI_ClientSideException, exceptionToThrow); this.callback.SendResponse(exceptionMessage); } finally { // Two threads are involved here: // first thread: it is disposing BrokerClient, and now it is at WebBrokerFrontendForGetResponse.Dispose // second thread: it is "ParsingResponseThreadProc" worker thread // The first thread holds a lock "lockObjectToProtectHandlers" and calls WebResponseHandler.Dispose method, // which attempts to abort second thread. But the second thread is in finally block here, it indefinitely // delays the abort. So the first thread is blocked at "this.parsingResponseThread.Abort()". // The second thread calls following "this.Completed" method, which waits for the same lock "lockObjectToProtectHandlers". // So the second thread is blocked on that lock. // In order to avoid deadlock, change the first thread. It should not hold a lock when aborts the second thread. if (this.Completed != null) { this.Completed(this, EventArgs.Empty); } } }