[runtime] Fixed get_process_module module name.
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel / ChannelFactory_1Test.cs
1 //
2 // ChannelFactory_1Test.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections.ObjectModel;
31 using System.Runtime.Serialization;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.ServiceModel.Description;
35 using System.Threading;
36 using System.Xml;
37 using System.Xml.Serialization;
38 using MonoTests.System.ServiceModel.Channels;
39 using NUnit.Framework;
40
41 namespace MonoTests.System.ServiceModel
42 {
43         [TestFixture]
44         public class ChannelFactory_1Test
45         {
46                 class MyChannelFactory<T> : ChannelFactory<T>
47                 {
48                         public MyChannelFactory (Binding b, EndpointAddress a)
49                                 : base (b, a)
50                         {
51                         }
52
53                         public void OpenAnyways ()
54                         {
55                                 EnsureOpened ();
56                         }
57                 }
58
59                 [Test]
60                 [ExpectedException (typeof (InvalidOperationException))]
61                 public void CreateChannelForClass ()
62                 {
63                         //ChannelFactory<TestService> f =
64                                 new ChannelFactory<TestService> (
65                                         new BasicHttpBinding (),
66                                         new EndpointAddress ("http://localhost:37564"));
67                 }
68
69                 [Test]
70                 public void EndpointAddressAfterCreateChannel ()
71                 {
72                         var f = new ChannelFactory<ITestService> (new BasicHttpBinding ());
73                         f.CreateChannel (new EndpointAddress ("http://localhost:37564"), null);
74                         Assert.IsNull (f.Endpoint.Address, "#1");
75                 }
76
77                 [Test]
78                 [Ignore ("fails under .NET; I never bothered to fix the test")]
79                 public void CtorNullArgsAllowed ()
80                 {
81                         ChannelFactory<ICtorUseCase1> f1;
82                         f1 = new ChannelFactory<ICtorUseCase1> ("CtorUseCase1_1", null);
83                         Assert.AreEqual (new EndpointAddress ("http://test1_1"), f1.Endpoint.Address, "#01");
84                         f1 = new ChannelFactory<ICtorUseCase1> (new BasicHttpBinding (), (EndpointAddress)null);
85                         Assert.AreEqual (null, f1.Endpoint.Address, "#01");
86                 }
87
88                 [Test]
89                 [ExpectedException (typeof (InvalidOperationException))]
90                 public void CreateChannelFromDefaultConfigWithTwoConfigs ()
91                 {
92                         new ChannelFactory<ICtorUseCase2> ("*");
93                 }
94
95                 [Test]
96                 [ExpectedException (typeof (InvalidOperationException))]
97                 public void CreateChannelFromDefaultConfigWithNoConfigs ()
98                 {
99                         new ChannelFactory<ICtorUseCase3> ("*");
100                 }
101
102                 [Test]
103                 [ExpectedException (typeof (ArgumentNullException))]
104                 public void CtorArgsTest1 ()
105                 {
106                         new ChannelFactory<ICtorUseCase1> (new BasicHttpBinding (), (string)null);
107                 }
108
109                 [Test]
110                 [ExpectedException (typeof (InvalidOperationException))]
111                 public void CtorArgsTest2 ()
112                 {
113                         new ChannelFactory<ICtorUseCase1> ("CtorUseCase1_Incorrect");
114                 }
115
116                 [Test]
117                 [ExpectedException (typeof (ArgumentNullException))]
118                 public void CtorArgsTest3 ()
119                 {
120                         new ChannelFactory<ICtorUseCase1> ((string)null, new EndpointAddress ("http://test"));
121                 }
122
123                 [Test]
124                 [ExpectedException (typeof (ArgumentNullException))]
125                 public void ConstructorNullServiceEndpoint ()
126                 {
127                         new ChannelFactory<IFoo> ((ServiceEndpoint) null);
128                 }
129
130                 [Test]
131                 [ExpectedException (typeof (ArgumentNullException))]
132                 public void ConstructorNullBinding ()
133                 {
134                         new ChannelFactory<IFoo> ((Binding) null);
135                 }
136
137                 [Test]
138                 public void ConfigEmptyCtor ()
139                 {
140                         // It has no valid configuration, but goes on.
141                         new ChannelFactory<ICtorUseCase1> ();
142                 }
143
144                 [Test]
145                 [ExpectedException (typeof (InvalidOperationException))]
146                 public void ConfigEmptyCtor2 ()
147                 {
148                         var cf = new ChannelFactory<ICtorUseCase1> ();
149                         // It cannot go on further.
150                         cf.CreateChannel ();
151                 }
152
153                 [Test]
154                 [Ignore ("fails under .NET; I never bothered to fix the test")]
155                 public void ConfigCtor ()
156                 {
157                         new ChannelFactory<ICtorUseCase1> ("CtorUseCase1_1");
158                 }
159
160                 [Test]
161                 public void EnsureOpened ()
162                 {
163                         MyChannelFactory<ITestService> f =
164                                 new MyChannelFactory<ITestService> (
165                                         new BasicHttpBinding (),
166                                         new EndpointAddress ("http://localhost:37564"));
167                         Assert.AreEqual (CommunicationState.Created,
168                                 f.State, "#1");
169                         f.OpenAnyways ();
170                         Assert.AreEqual (CommunicationState.Opened,
171                                 f.State, "#1");
172                 }
173
174                 [Test]
175                 // I was deceived by MSDN and currently ChannelFactory<T>
176                 // only accepts IChannel as T. It will be fixed. -> done.
177                 public void CreateChannel ()
178                 {
179                         ChannelFactory<ITestService> f =
180                                 new ChannelFactory<ITestService> (
181                                         new BasicHttpBinding (),
182                                         new EndpointAddress ("http://localhost:37564"));
183                         f.CreateChannel ();
184                 }
185
186                 private T CreateChannel<T> (RequestSender handler)
187                 {
188                         CustomBinding b = new CustomBinding (new HandlerTransportBindingElement (handler));
189                         ChannelFactory<T> f = new ChannelFactory<T> ( b, new EndpointAddress ("urn:dummy"));
190                         return f.CreateChannel ();
191                 }
192
193                 [Test]
194                 public void InvokeFoo ()
195                 {
196                         ITestService ts = CreateChannel<ITestService> (
197                                 delegate (Message input) {
198                                         BodyWriter bw = new HandlerBodyWriter (
199                                                 delegate (XmlDictionaryWriter writer) {
200                                                         writer.WriteStartElement ("FooResponse", "http://tempuri.org/");
201                                                         writer.WriteElementString ("FooResult", "http://tempuri.org/", "cecil");
202                                                         writer.WriteEndElement ();
203                                                 }
204                                         );
205                                         return Message.CreateMessage (input.Version, input.Headers.Action + "Response", bw);
206                                 }
207                         );
208                         Assert.AreEqual ("cecil", ts.Foo ("il offre sa confiance et son amour"));
209                 }
210
211                 [Test]
212                 public void InvokeBar ()
213                 {
214                         ITestService ts = CreateChannel<ITestService> (
215                                 delegate (Message input) {
216                                         BodyWriter bw = new HandlerBodyWriter (
217                                                 delegate (XmlDictionaryWriter writer) {
218                                                         writer.WriteStartElement ("BarResponse", "http://tempuri.org/");
219                                                         writer.WriteElementString ("DummyBarResponse", "http://tempuri.org/", "cecil");
220                                                         writer.WriteEndElement ();
221                                                 }
222                                         );
223                                         return Message.CreateMessage (input.Version, input.Headers.Action + "Response", bw);
224                                 }
225                         );
226                         ts.Bar ("il offre sa confiance et son amour");
227                 }
228
229                 Message ToMessage<T> (Message input, bool isXml, T val)
230                 {
231                         TypedMessageConverter tm;
232                         if (isXml)
233                                 tm = TypedMessageConverter.Create (typeof (T),
234                                         input.Headers.Action + "Response", new XmlSerializerFormatAttribute ());
235                         else
236                                 tm = TypedMessageConverter.Create (typeof (T),
237                                         input.Headers.Action + "Response");
238                         return tm.ToMessage (val, input.Version);
239                 }
240
241                 T FromMessage<T> (Message input, bool isXml)
242                 {
243                         TypedMessageConverter tm;
244                         if (isXml)
245                                 tm = TypedMessageConverter.Create (typeof (T), input.Headers.Action,
246                                         new XmlSerializerFormatAttribute ());
247                         else
248                                 tm = TypedMessageConverter.Create (typeof (T), input.Headers.Action);
249                         return (T)tm.FromMessage (input);
250                 }
251
252                 [Test]
253                 public void InvokeFooOutEnumParam ()
254                 {
255                         ITestService ts = CreateChannel<ITestService> (
256                                 delegate (Message input) {
257                                         // Test input for in and out Enum args.
258                                         XmlDocument doc = new XmlDocument ();
259                                         doc.LoadXml (input.ToString ());
260
261                                         XmlNamespaceManager nss = new XmlNamespaceManager (doc.NameTable);
262                                         nss.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
263                                         nss.AddNamespace ("t", "http://tempuri.org/");
264                                         XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/t:FooOutEnumParam", nss) as XmlElement;
265                                         Assert.IsNotNull (el, "I#0");
266                                         XmlNode arg1 = el.SelectSingleNode ("t:arg1", nss);
267                                         Assert.IsNotNull (arg1, "I#2");
268                                         Assert.AreEqual ("Blue", arg1.InnerText, "I#3");
269
270                                         return ToMessage (input, false,
271                                                 new FooOutEnumParamResponse (FooColor.Green, FooColor.Red));
272                                 }
273                         );
274
275                         FooColor argOut;
276                         FooColor res = ts.FooOutEnumParam (FooColor.Blue, out argOut);
277                         Assert.AreEqual (FooColor.Green, res, "#1");
278                         Assert.AreEqual (FooColor.Red, argOut, "#2");
279                 }
280
281                 public T CreateVoidFooOutParamChannel<T> (bool isXml)
282                 {
283                         return CreateChannel<T> (
284                                 delegate (Message input) {
285                                         // Test input for in and ref args.
286                                         XmlDocument doc = new XmlDocument ();
287                                         doc.LoadXml (input.ToString ());
288
289                                         XmlNamespaceManager nss = new XmlNamespaceManager (doc.NameTable);
290                                         nss.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
291                                         nss.AddNamespace ("t", "http://tempuri.org/");
292                                         XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/t:VoidFooOutParam", nss) as XmlElement;
293                                         Assert.IsNotNull (el, "I#0");
294                                         XmlNode arg1 = el.SelectSingleNode ("t:arg1", nss);
295                                         Assert.IsNotNull (arg1, "I#2");
296                                         Assert.AreEqual ("testIt", arg1.InnerText, "I#3");
297                                         XmlNode arg2 = el.SelectSingleNode ("t:arg2", nss);
298                                         Assert.IsNotNull (arg2, "I#4");
299                                         Assert.AreEqual ("testRef", arg2.InnerText, "I#4");
300
301                                         return ToMessage (input, isXml,
302                                                 new VoidFooOutParamResponse ("refArg", "outArg"));
303                                 }
304                         );
305                 }
306
307                 [Test]
308                 public void InvokeVoidFooOutParam ()
309                 {
310                         ITestService ts = CreateVoidFooOutParamChannel<ITestService> (false);
311                         string argRef = "testRef";
312                         string argOut;
313                         ts.VoidFooOutParam ("testIt", ref argRef, out argOut);
314                         Assert.AreEqual ("refArg", argRef, "#1");
315                         Assert.AreEqual ("outArg", argOut, "#2");
316                 }
317
318                 [Test]
319                 public void XmlInvokeVoidFooOutParam ()
320                 {
321                         ITestServiceXml ts = CreateVoidFooOutParamChannel<ITestServiceXml> (true);
322                         string argRef = "testRef";
323                         string argOut;
324                         ts.VoidFooOutParam ("testIt", ref argRef, out argOut);
325                         Assert.AreEqual ("refArg", argRef, "#1");
326                         Assert.AreEqual ("outArg", argOut, "#2");
327                 }
328
329                 public T CreateFooOutParamChannel<T> (bool isXml)
330                 {
331                         return CreateChannel<T> (
332                                 delegate (Message input) {
333                                         // Test input for in and ref args.
334                                         XmlDocument doc = new XmlDocument ();
335                                         doc.LoadXml (input.ToString ());
336
337                                         XmlNamespaceManager nss = new XmlNamespaceManager (doc.NameTable);
338                                         nss.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
339                                         nss.AddNamespace ("t", "http://tempuri.org/");
340                                         XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/t:FooOutParam", nss) as XmlElement;
341                                         Assert.IsNotNull (el, "I#0");
342                                         XmlNode arg1 = el.SelectSingleNode ("t:arg1", nss);
343                                         Assert.IsNotNull (arg1, "I#2");
344                                         Assert.AreEqual ("testIt", arg1.InnerText, "I#3");
345                                         XmlNode arg2 = el.SelectSingleNode ("t:arg2", nss);
346                                         Assert.IsNotNull (arg2, "I#4");
347                                         Assert.AreEqual ("testRef", arg2.InnerText, "I#4");
348
349                                         return ToMessage (input, isXml,
350                                                 new FooOutParamResponse ("callResult", "refArg", "outArg"));
351                                 }
352                         );
353                 }
354
355                 [Test]
356                 public void InvokeFooOutParam ()
357                 {
358                         ITestService ts = CreateFooOutParamChannel<ITestService> (false);
359                         string argRef = "testRef";
360                         string argOut;
361                         string res = ts.FooOutParam ("testIt", ref argRef, out argOut);
362                         Assert.AreEqual ("callResult", res, "#1");
363                         Assert.AreEqual ("refArg", argRef, "#2");
364                         Assert.AreEqual ("outArg", argOut, "#3");
365                 }
366
367                 [Test]
368                 public void XmlInvokeFooOutParam ()
369                 {
370                         ITestServiceXml ts = CreateFooOutParamChannel<ITestServiceXml> (true);
371                         string argRef = "testRef";
372                         string argOut;
373                         string res = ts.FooOutParam ("testIt", ref argRef, out argOut);
374                         Assert.AreEqual ("callResult", res, "#1");
375                         Assert.AreEqual ("refArg", argRef, "#2");
376                         Assert.AreEqual ("outArg", argOut, "#3");
377                 }
378
379                 [Test]
380                 public void InvokeFooComplex ()
381                 {
382                         ITestService ts = CreateChannel<ITestService> (
383                                 delegate (Message input) {
384                                         // Test input for in and ref args.
385                                         XmlDocument doc = new XmlDocument ();
386                                         doc.LoadXml (input.ToString ());
387
388                                         XmlNamespaceManager nss = new XmlNamespaceManager (doc.NameTable);
389                                         nss.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
390                                         nss.AddNamespace ("t", "http://tempuri.org/");
391                                         nss.AddNamespace ("v", "http://schemas.datacontract.org/2004/07/MonoTests.System.ServiceModel");
392                                         XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/t:FooComplex", nss) as XmlElement;
393                                         Assert.IsNotNull (el, "I#0");
394                                         XmlNode arg1 = el.SelectSingleNode ("t:arg1/v:val", nss);
395                                         Assert.IsNotNull (arg1, "I#2");
396                                         Assert.AreEqual ("testIt", arg1.InnerText, "I#3");
397
398                                         return ToMessage (input, false, new FooComplexResponse ("callResult"));
399                                 }
400                         );
401
402                         TestData res = ts.FooComplex (new TestData ("testIt"));
403                         Assert.IsNotNull (res, "#1");
404                         Assert.AreEqual ("callResult", res.val, "#2");
405                 }
406
407                 [Test]
408                 [Ignore ("This somehow results in an infinite loop")]
409                 public void XmlInvokeFooComplex ()
410                 {
411                         ITestServiceXml ts = CreateChannel<ITestServiceXml> (
412                                 delegate (Message input) {
413                                         // Test input for in and ref args.
414                                         XmlDocument doc = new XmlDocument ();
415                                         doc.LoadXml (input.ToString ());
416
417                                         XmlNamespaceManager nss = new XmlNamespaceManager (doc.NameTable);
418                                         nss.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
419                                         nss.AddNamespace ("t", "http://tempuri.org/");
420                                         XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/t:FooComplex", nss) as XmlElement;
421                                         Assert.IsNotNull (el, "I#0");
422                                         XmlElement arg1 = el.SelectSingleNode ("t:arg1", nss) as XmlElement;
423                                         Assert.IsNotNull (arg1, "I#2");
424                                         Assert.AreEqual ("testIt", arg1.GetAttribute ("val"), "I#3");
425
426                                         return ToMessage (input, true, new FooComplexResponse ("callResult"));
427                                 }
428                         );
429
430                         TestData res = ts.FooComplex (new TestData ("testIt"));
431                         Assert.IsNotNull (res, "#1");
432                         Assert.AreEqual ("callResult", res.val, "#2");
433                 }
434
435 #if NET_4_0
436                 [Test]
437                 public void ConstructorServiceEndpoint ()
438                 {
439                         // It is okay to pass ServiceEndpoint that does not have Binding or EndpointAddress.
440                         new ChannelFactory<IRequestChannel> (new ServiceEndpoint (ContractDescription.GetContract (typeof (IMetadataExchange)), null, null));
441                 }
442 #endif
443
444                 public T CreateFooComplexMC_Channel<T> (bool isXml)
445                 {
446                         return CreateChannel<T> (
447                                 delegate (Message input) {
448                                         TestMessage arg = FromMessage<TestMessage> (input, isXml);
449                                         Assert.IsNotNull (arg.data, "I#0");
450                                         Assert.AreEqual (arg.data.val, "testIt", "I#1");
451                                         Assert.IsNotNull (arg.msg, "I#2");
452                                         Assert.AreEqual (arg.msg.val, "testMsg", "I#3");
453
454                                         return ToMessage (input, isXml, new TestResult ("callResult", "callArg"));
455                                 }
456                         );
457                 }
458
459                 [Test]
460                 public void InvokeFooComplexMC ()
461                 {
462                         ITestService ts = CreateFooComplexMC_Channel<ITestService> (false);
463                         TestResult res = ts.FooComplexMC (new TestMessage ("testIt", "testMsg"));
464                         Assert.IsNotNull (res, "#1");
465                         Assert.AreEqual ("callResult", res.resData.val, "#2");
466                         Assert.AreEqual ("callArg", res.resMsg.val, "#3");
467                 }
468
469                 [Test]
470                 [Ignore ("This somehow results in an infinite loop")]
471                 public void XmlInvokeFooComplexMC ()
472                 {
473                         ITestServiceXml ts = CreateFooComplexMC_Channel<ITestServiceXml> (true);
474                         TestResult res = ts.FooComplexMC (new TestMessage ("testIt", "testMsg"));
475                         Assert.IsNotNull (res, "#1");
476                         Assert.AreEqual ("callResult", res.resData.val, "#2");
477                         Assert.AreEqual ("callArg", res.resMsg.val, "#3");
478                 }
479
480                 [Test]
481                 public void OneWayOperationWithRequestReplyChannel ()
482                 {
483                         var host = new ServiceHost (typeof (OneWayService));
484                         host.AddServiceEndpoint (typeof (IOneWayService),
485                                 new BasicHttpBinding (),
486                                 new Uri ("http://localhost:30158"));
487                         host.Open ();
488                         try {
489                                 var cf = new ChannelFactory<IOneWayService> (
490                                         new BasicHttpBinding (),
491                                         new EndpointAddress ("http://localhost:30158"));
492                                 var ch = cf.CreateChannel ();
493                                 ch.GiveMessage ("test");
494                                 
495                                 Assert.IsTrue (OneWayService.WaitHandle.WaitOne (TimeSpan.FromSeconds (5)), "#1");
496                         } finally {
497                                 host.Close ();
498                         }
499                 }
500
501                 [ServiceContract]
502                 public interface ITestService
503                 {
504                         [OperationContract]
505                         string Foo (string arg);
506
507                         [OperationContract]
508                         void Bar (string arg);
509
510                         [OperationContract]
511                         void Foo1 (string arg1, string arg2);
512
513                         [OperationContract]
514                         FooColor FooOutEnumParam (FooColor arg1, out FooColor arg2);
515
516                         [OperationContract]
517                         string FooOutParam (string arg1, ref string arg2, out string arg3);
518
519                         [OperationContract]
520                         void VoidFooOutParam (string arg1, ref string arg2, out string arg3);
521
522                         [OperationContract]
523                         TestData FooComplex (TestData arg1);
524
525                         [OperationContract]
526                         TestResult FooComplexMC (TestMessage arg1);
527                 }
528
529                 [ServiceContract]
530                 public interface ITestServiceXml
531                 {
532                         [OperationContract]
533                         string FooOutParam (string arg1, ref string arg2, out string arg3);
534
535                         [OperationContract]
536                         void VoidFooOutParam (string arg1, ref string arg2, out string arg3);
537
538                         [OperationContract]
539                         [XmlSerializerFormat]
540                         TestData FooComplex (TestData arg1);
541
542                         [OperationContract]
543                         [XmlSerializerFormat]
544                         TestResult FooComplexMC (TestMessage arg1);
545                 }
546
547                 [ServiceContract]
548                 public interface IOneWayService
549                 {
550                         [OperationContract (IsOneWay = true)]
551                         void GiveMessage (string input);
552                 }
553
554                 public class OneWayService : IOneWayService
555                 {
556                         public static ManualResetEvent WaitHandle = new ManualResetEvent (false);
557
558                         public void GiveMessage (string input)
559                         {
560                                 WaitHandle.Set ();
561                         }
562                 }
563
564                 public enum FooColor { Red = 1, Green, Blue }
565
566                 [DataContract]
567                 public class TestData
568                 {
569                         TestData () {}
570                         public TestData (string val) { this.val = val; }
571
572                         [DataMember]
573                         [XmlAttribute]
574                         public string val;
575                 }
576
577                 [MessageContract]
578                 public class TestMessage
579                 {
580                         TestMessage () {}
581                         public TestMessage (string a, string b) { data = new TestData (a); msg = new TestData (b); }
582
583                         [MessageBodyMember]
584                         public TestData data;
585
586                         [MessageBodyMember]
587                         public TestData msg;
588                 }
589
590                 [MessageContract]
591                 public class TestResult
592                 {
593                         TestResult () {}
594                         public TestResult (string a, string b) { resData = new TestData (a); resMsg = new TestData (b); }
595
596                         [MessageBodyMember]
597                         public TestData resData;
598
599                         [MessageBodyMember]
600                         public TestData resMsg;
601                 }
602
603                 [MessageContract (WrapperNamespace = "http://tempuri.org/")]
604                 class FooOutParamResponse
605                 {
606                         FooOutParamResponse () {}
607                         public FooOutParamResponse (string ret, string refArg, string outArg) { FooOutParamResult = ret; this.arg2 = refArg; this.arg3 = outArg; }
608
609                         [MessageBodyMember]
610                         public string FooOutParamResult;
611
612                         [MessageBodyMember]
613                         public string arg2;
614
615                         [MessageBodyMember]
616                         public string arg3;
617                 }
618
619                 [MessageContract (WrapperNamespace = "http://tempuri.org/")]
620                 class FooOutEnumParamResponse
621                 {
622                         FooOutEnumParamResponse () {}
623                         public FooOutEnumParamResponse (FooColor ret, FooColor outArg) { FooOutEnumParamResult = ret; this.arg2 = outArg; }
624
625                         [MessageBodyMember]
626                         public FooColor FooOutEnumParamResult;
627
628                         [MessageBodyMember]
629                         public FooColor arg2;
630                 }
631
632                 [MessageContract (WrapperNamespace = "http://tempuri.org/")]
633                 class VoidFooOutParamResponse
634                 {
635                         VoidFooOutParamResponse () {}
636                         public VoidFooOutParamResponse (string refArg, string outArg) { this.arg2 = refArg; this.arg3 = outArg; }
637
638                         [MessageBodyMember]
639                         public string arg2;
640
641                         [MessageBodyMember]
642                         public string arg3;
643                 }
644
645                 [MessageContract (WrapperNamespace = "http://tempuri.org/")]
646                 class FooComplexResponse
647                 {
648                         FooComplexResponse () {}
649                         public FooComplexResponse (string val) { FooComplexResult  = new TestData (val); }
650
651                         [MessageBodyMember]
652                         public TestData FooComplexResult;
653                 }
654
655                 class TestService
656                 {
657                         public string Foo (string arg)
658                         {
659                                 return arg;
660                         }
661                 }
662         }
663 }