2 // System.Runtime.Remoting.Channels.SoapClientFormatterSink.cs
\r
4 // Authors: Rodrigo Moya (rodrigo@ximian.com)
\r
5 // Jean-Marc André (jean-marc.andre@polymtl.ca)
\r
7 // 2002 (C) Copyright, Ximian, Inc.
\r
11 // Permission is hereby granted, free of charge, to any person obtaining
\r
12 // a copy of this software and associated documentation files (the
\r
13 // "Software"), to deal in the Software without restriction, including
\r
14 // without limitation the rights to use, copy, modify, merge, publish,
\r
15 // distribute, sublicense, and/or sell copies of the Software, and to
\r
16 // permit persons to whom the Software is furnished to do so, subject to
\r
17 // the following conditions:
\r
19 // The above copyright notice and this permission notice shall be
\r
20 // included in all copies or substantial portions of the Software.
\r
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
31 using System.Collections;
\r
33 using System.Reflection;
\r
34 using System.Runtime.Remoting.Messaging;
\r
35 using System.Runtime.Serialization;
\r
36 using System.Runtime.Serialization.Formatters;
\r
37 using System.Runtime.Serialization.Formatters.Soap;
\r
39 namespace System.Runtime.Remoting.Channels
\r
41 public class SoapClientFormatterSink : IClientFormatterSink,
\r
42 IMessageSink, IClientChannelSink, IChannelSinkBase
\r
44 private IClientChannelSink _nextChannelSink;
\r
45 private SoapCore _soapCore = SoapCore.DefaultInstance;
\r
47 public SoapClientFormatterSink (IClientChannelSink sink)
\r
49 _nextChannelSink = sink;
\r
52 internal SoapCore SoapCore
\r
54 get { return _soapCore; }
\r
55 set { _soapCore = value; }
\r
58 // IClientChannelSink
\r
59 public IClientChannelSink NextChannelSink
\r
62 return _nextChannelSink;
\r
67 public IMessageSink NextSink
\r
75 public IDictionary Properties
\r
82 public IMessageCtrl AsyncProcessMessage (IMessage msg,
\r
83 IMessageSink replySink)
\r
85 Stream requestStream;
\r
86 ITransportHeaders requestHeaders;
\r
87 SoapMessageFormatter soapMsgFormatter;
\r
89 SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);
\r
91 ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
\r
92 stack.Push(this, new CallData (msg, soapMsgFormatter));
\r
94 _nextChannelSink.AsyncProcessRequest(stack, msg, requestHeaders, requestStream);
\r
99 public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
\r
101 ITransportHeaders headers,
\r
104 // this method should never be called
\r
105 throw new NotSupportedException ();
\r
108 public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
\r
110 ITransportHeaders headers,
\r
113 CallData data = (CallData)state;
\r
114 SoapMessageFormatter soapMsgFormatter = data.Formatter;
\r
115 IMessage replyMessage = (IMessage) DeserializeMessage(stream, headers, (IMethodCallMessage)data.Msg, soapMsgFormatter);
\r
116 sinkStack.DispatchReplyMessage(replyMessage);
\r
120 public Stream GetRequestStream (IMessage msg,
\r
121 ITransportHeaders headers)
\r
123 // First sink in the chain so this method should never
\r
125 throw new NotSupportedException ();
\r
128 public void ProcessMessage (IMessage msg,
\r
129 ITransportHeaders requestHeaders,
\r
130 Stream requestStream,
\r
131 out ITransportHeaders responseHeaders,
\r
132 out Stream responseStream)
\r
134 // First sink in the chain so this method should never
\r
136 throw new NotSupportedException ();
\r
140 public IMessage SyncProcessMessage (IMessage msg)
\r
142 Stream requestStream, responseStream;
\r
143 ITransportHeaders requestHeaders, responseHeaders;
\r
144 SoapMessageFormatter soapMsgFormatter;
\r
146 SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);
\r
147 _nextChannelSink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);
\r
149 return DeserializeMessage(responseStream, responseHeaders, (IMethodCallMessage)msg, soapMsgFormatter);
\r
153 private void SerializeMessage(IMessage msg, out Stream requestStream, out ITransportHeaders requestHeaders, out SoapMessageFormatter soapMsgFormatter) {
\r
154 SoapMessage soapMsg;
\r
155 soapMsgFormatter = new SoapMessageFormatter();
\r
156 soapMsg = soapMsgFormatter.BuildSoapMessageFromMethodCall((IMethodCallMessage) msg, out requestHeaders);
\r
158 // Get the stream where the message will be serialized
\r
159 requestStream = _nextChannelSink.GetRequestStream(msg, requestHeaders);
\r
161 if(requestStream == null) requestStream = new MemoryStream();
\r
163 // Serialize the message into the stream
\r
164 _soapCore.Serializer.Serialize(requestStream, soapMsg, null);
\r
166 if(requestStream is MemoryStream){
\r
167 requestStream.Position = 0;
\r
172 private IMessage DeserializeMessage(Stream responseStream, ITransportHeaders responseHeaders,IMethodCallMessage mcm, SoapMessageFormatter soapMsgFormatter)
\r
174 SoapFormatter fm = _soapCore.GetSafeDeserializer ();
\r
175 SoapMessage rtnMessage = soapMsgFormatter.CreateSoapMessage (false);
\r
176 fm.TopObject = rtnMessage;
\r
177 object objReturn = fm.Deserialize(responseStream);
\r
179 if (objReturn is SoapFault)
\r
180 return soapMsgFormatter.FormatFault ((SoapFault) objReturn, mcm);
\r
182 return soapMsgFormatter.FormatResponse ((ISoapMessage) objReturn, mcm);
\r
187 public CallData (IMessage msg, SoapMessageFormatter formatter) { Msg = msg; Formatter = formatter; }
\r
188 public IMessage Msg;
\r
189 public SoapMessageFormatter Formatter;
\r