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 nextSink)
\r
49 _nextChannelSink = nextSink;
\r
52 internal SoapCore SoapCore {
\r
53 get { return _soapCore; }
\r
54 set { _soapCore = value; }
\r
57 // IClientChannelSink
\r
58 public IClientChannelSink NextChannelSink {
\r
60 return _nextChannelSink;
\r
65 public IMessageSink NextSink {
\r
72 public IDictionary Properties {
\r
78 public IMessageCtrl AsyncProcessMessage (IMessage msg,
\r
79 IMessageSink replySink)
\r
81 Stream requestStream;
\r
82 ITransportHeaders requestHeaders;
\r
83 SoapMessageFormatter soapMsgFormatter;
\r
85 SerializeMessage (msg, out requestStream, out requestHeaders,
\r
86 out soapMsgFormatter);
\r
88 ClientChannelSinkStack stack = new ClientChannelSinkStack (replySink);
\r
89 stack.Push(this, new CallData (msg, soapMsgFormatter));
\r
91 _nextChannelSink.AsyncProcessRequest (stack, msg, requestHeaders, requestStream);
\r
96 public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
\r
98 ITransportHeaders headers,
\r
101 // this method should never be called
\r
102 throw new NotSupportedException ();
\r
105 public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
\r
107 ITransportHeaders headers,
\r
110 CallData data = (CallData) state;
\r
111 SoapMessageFormatter soapMsgFormatter = data.Formatter;
\r
112 IMessage replyMessage = (IMessage) DeserializeMessage (
\r
113 stream, headers, (IMethodCallMessage) data.Msg,
\r
115 sinkStack.DispatchReplyMessage (replyMessage);
\r
119 public Stream GetRequestStream (IMessage msg,
\r
120 ITransportHeaders headers)
\r
122 // First sink in the chain so this method should never
\r
124 throw new NotSupportedException ();
\r
127 public void ProcessMessage (IMessage msg,
\r
128 ITransportHeaders requestHeaders,
\r
129 Stream requestStream,
\r
130 out ITransportHeaders responseHeaders,
\r
131 out Stream responseStream)
\r
133 // First sink in the chain so this method should never
\r
135 throw new NotSupportedException ();
\r
139 public IMessage SyncProcessMessage (IMessage msg)
\r
141 Stream requestStream, responseStream;
\r
142 ITransportHeaders requestHeaders, responseHeaders;
\r
143 SoapMessageFormatter soapMsgFormatter;
\r
145 SerializeMessage (msg, out requestStream, out requestHeaders,
\r
146 out soapMsgFormatter);
\r
147 _nextChannelSink.ProcessMessage(msg, requestHeaders,
\r
148 requestStream, out responseHeaders,
\r
149 out responseStream);
\r
151 return DeserializeMessage(responseStream, responseHeaders,
\r
152 (IMethodCallMessage) msg, soapMsgFormatter);
\r
156 private void SerializeMessage(IMessage msg, out Stream requestStream, out ITransportHeaders requestHeaders, out SoapMessageFormatter soapMsgFormatter) {
\r
157 SoapMessage soapMsg;
\r
158 soapMsgFormatter = new SoapMessageFormatter();
\r
159 soapMsg = soapMsgFormatter.BuildSoapMessageFromMethodCall (
\r
160 (IMethodCallMessage) msg, out requestHeaders);
\r
162 // Get the stream where the message will be serialized
\r
163 requestStream = _nextChannelSink.GetRequestStream (msg,
\r
166 if (requestStream == null)
\r
167 requestStream = new MemoryStream();
\r
169 // Serialize the message into the stream
\r
170 _soapCore.Serializer.Serialize(requestStream, soapMsg, null);
\r
172 if (requestStream is MemoryStream)
\r
173 requestStream.Position = 0;
\r
177 private IMessage DeserializeMessage(Stream responseStream, ITransportHeaders responseHeaders,IMethodCallMessage mcm, SoapMessageFormatter soapMsgFormatter)
\r
179 SoapFormatter fm = _soapCore.GetSafeDeserializer ();
\r
180 SoapMessage rtnMessage = soapMsgFormatter.CreateSoapMessage (false);
\r
181 fm.TopObject = rtnMessage;
\r
182 object objReturn = fm.Deserialize(responseStream);
\r
184 if (objReturn is SoapFault)
\r
185 return soapMsgFormatter.FormatFault ((SoapFault) objReturn, mcm);
\r
187 return soapMsgFormatter.FormatResponse ((ISoapMessage) objReturn, mcm);
\r
192 public CallData (IMessage msg, SoapMessageFormatter formatter)
\r
195 Formatter = formatter;
\r
198 public IMessage Msg;
\r
199 public SoapMessageFormatter Formatter;
\r