SoapClientFormatterSink.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //
  2. // System.Runtime.Remoting.Channels.SoapClientFormatterSink.cs
  3. //
  4. // Authors: Rodrigo Moya ([email protected])
  5. // Jean-Marc André ([email protected])
  6. //
  7. // 2002 (C) Copyright, Ximian, Inc.
  8. //
  9. using System.Collections;
  10. using System.IO;
  11. using System.Reflection;
  12. using System.Runtime.Remoting.Messaging;
  13. using System.Runtime.Serialization;
  14. using System.Runtime.Serialization.Formatters;
  15. using System.Runtime.Serialization.Formatters.Soap;
  16. namespace System.Runtime.Remoting.Channels
  17. {
  18. public class SoapClientFormatterSink : IClientFormatterSink,
  19. IMessageSink, IClientChannelSink, IChannelSinkBase
  20. {
  21. private IClientChannelSink _nextChannelSink;
  22. private SoapCore _soapCore = SoapCore.DefaultInstance;
  23. public SoapClientFormatterSink (IClientChannelSink sink)
  24. {
  25. _nextChannelSink = sink;
  26. }
  27. internal SoapCore SoapCore
  28. {
  29. get { return _soapCore; }
  30. set { _soapCore = value; }
  31. }
  32. // IClientChannelSink
  33. public IClientChannelSink NextChannelSink
  34. {
  35. get {
  36. return _nextChannelSink;
  37. }
  38. }
  39. // IMessageSink
  40. public IMessageSink NextSink
  41. {
  42. get {
  43. return null ;
  44. }
  45. }
  46. // IChannelSinkBase
  47. public IDictionary Properties
  48. {
  49. get {
  50. return null;
  51. }
  52. }
  53. public IMessageCtrl AsyncProcessMessage (IMessage msg,
  54. IMessageSink replySink)
  55. {
  56. Stream requestStream;
  57. ITransportHeaders requestHeaders;
  58. SoapMessageFormatter soapMsgFormatter;
  59. SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);
  60. ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
  61. stack.Push(this, new CallData (msg, soapMsgFormatter));
  62. _nextChannelSink.AsyncProcessRequest(stack, msg, requestHeaders, requestStream);
  63. return null;
  64. }
  65. public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
  66. IMessage msg,
  67. ITransportHeaders headers,
  68. Stream stream)
  69. {
  70. // this method should never be called
  71. throw new NotSupportedException ();
  72. }
  73. public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
  74. object state,
  75. ITransportHeaders headers,
  76. Stream stream)
  77. {
  78. CallData data = (CallData)state;
  79. SoapMessageFormatter soapMsgFormatter = data.Formatter;
  80. IMessage replyMessage = (IMessage) DeserializeMessage(stream, headers, (IMethodCallMessage)data.Msg, soapMsgFormatter);
  81. sinkStack.DispatchReplyMessage(replyMessage);
  82. }
  83. public Stream GetRequestStream (IMessage msg,
  84. ITransportHeaders headers)
  85. {
  86. // First sink in the chain so this method should never
  87. // be called
  88. throw new NotSupportedException ();
  89. }
  90. public void ProcessMessage (IMessage msg,
  91. ITransportHeaders requestHeaders,
  92. Stream requestStream,
  93. out ITransportHeaders responseHeaders,
  94. out Stream responseStream)
  95. {
  96. // First sink in the chain so this method should never
  97. // be called
  98. throw new NotSupportedException ();
  99. }
  100. public IMessage SyncProcessMessage (IMessage msg)
  101. {
  102. Stream requestStream, responseStream;
  103. ITransportHeaders requestHeaders, responseHeaders;
  104. SoapMessageFormatter soapMsgFormatter;
  105. SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);
  106. _nextChannelSink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);
  107. return DeserializeMessage(responseStream, responseHeaders, (IMethodCallMessage)msg, soapMsgFormatter);
  108. }
  109. private void SerializeMessage(IMessage msg, out Stream requestStream, out ITransportHeaders requestHeaders, out SoapMessageFormatter soapMsgFormatter) {
  110. SoapMessage soapMsg;
  111. soapMsgFormatter = new SoapMessageFormatter();
  112. soapMsg = soapMsgFormatter.BuildSoapMessageFromMethodCall((IMethodCallMessage) msg, out requestHeaders);
  113. // Get the stream where the message will be serialized
  114. requestStream = _nextChannelSink.GetRequestStream(msg, requestHeaders);
  115. if(requestStream == null) requestStream = new MemoryStream();
  116. // Serialize the message into the stream
  117. _soapCore.Serializer.Serialize(requestStream, soapMsg, null);
  118. if(requestStream is MemoryStream){
  119. requestStream.Position = 0;
  120. }
  121. }
  122. private IMessage DeserializeMessage(Stream responseStream, ITransportHeaders responseHeaders,IMethodCallMessage mcm, SoapMessageFormatter soapMsgFormatter)
  123. {
  124. SoapFormatter fm = _soapCore.GetSafeDeserializer ();
  125. SoapMessage rtnMessage = new SoapMessage();
  126. fm.TopObject = rtnMessage;
  127. object objReturn = fm.Deserialize(responseStream);
  128. return soapMsgFormatter.FormatResponse((ISoapMessage) objReturn, mcm);
  129. }
  130. class CallData
  131. {
  132. public CallData (IMessage msg, SoapMessageFormatter formatter) { Msg = msg; Formatter = formatter; }
  133. public IMessage Msg;
  134. public SoapMessageFormatter Formatter;
  135. }
  136. }
  137. }