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