Support ServiceKnownTypes. Fixed another case on bug #652331.
authorAtsushi Eno <atsushi@ximian.com>
Wed, 9 Feb 2011 06:42:40 +0000 (15:42 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Wed, 9 Feb 2011 06:42:40 +0000 (15:42 +0900)
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs
mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources
mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug652331Test.cs [new file with mode: 0644]

index a4b5159fa38712a7e11f1588af8c8569866287bf..79af8ae0d25e61f97eb765be54e2842cf4abca5b 100644 (file)
@@ -111,6 +111,7 @@ namespace System.ServiceModel.Dispatcher
                bool isAsync;
                ParameterInfo [] requestMethodParams;
                ParameterInfo [] replyMethodParams;
+               List<Type> operation_known_types = new List<Type> ();
 
                public BaseMessagesFormatter (MessageDescriptionCollection messages)
                {
@@ -133,6 +134,7 @@ namespace System.ServiceModel.Dispatcher
                        methodParams = desc.EndMethod.GetParameters ();
                        replyMethodParams = new ParameterInfo [methodParams.Length - 1];
                        Array.Copy (methodParams, replyMethodParams, replyMethodParams.Length);
+                       operation_known_types.AddRange (desc.KnownTypes);
                }
 
                public static BaseMessagesFormatter Create (OperationDescription desc)
@@ -152,6 +154,10 @@ namespace System.ServiceModel.Dispatcher
                        return new DataContractMessagesFormatter (desc, dataAttr);
                }
 
+               public IEnumerable<Type> OperationKnownTypes {
+                       get { return operation_known_types; }
+               }
+
                protected abstract Message PartsToMessage (
                        MessageDescription md, MessageVersion version, string action, object [] parts);
                protected abstract object [] MessageToParts (MessageDescription md, Message message);
@@ -334,7 +340,6 @@ namespace System.ServiceModel.Dispatcher
                        return (object []) GetSerializer (md.Body).Deserialize (r);
                }
 
-               // FIXME: Handle ServiceKnownTypes
                XmlSerializer GetSerializer (MessageBodyDescription desc)
                {
                        if (bodySerializers.ContainsKey (desc))
@@ -350,8 +355,10 @@ namespace System.ServiceModel.Dispatcher
                        foreach (MessagePartDescription partDesc in desc.Parts)
                                members [ind++] = CreateReflectionMember (partDesc, false);
 
-                       // FIXME: Register known types into xmlImporter.
                        XmlReflectionImporter xmlImporter = new XmlReflectionImporter ();
+                       // Register known types into xmlImporter.
+                       foreach (var type in OperationKnownTypes)
+                               xmlImporter.IncludeType (type);
                        XmlMembersMapping [] partsMapping = new XmlMembersMapping [1];
                        partsMapping [0] = xmlImporter.ImportMembersMapping (desc.WrapperName, desc.WrapperNamespace, members, true);
                        bodySerializers [desc] = XmlSerializer.FromMappings (partsMapping) [0];
@@ -440,12 +447,11 @@ namespace System.ServiceModel.Dispatcher
                        return parts;
                }
 
-               // FIXME: Handle ServiceKnownTypes
                XmlObjectSerializer GetSerializer (MessagePartDescription partDesc)
                {
                        if (!serializers.ContainsKey (partDesc))
                                serializers [partDesc] = new DataContractSerializer (
-                                       partDesc.Type, partDesc.Name, partDesc.Namespace);
+                                       partDesc.Type, partDesc.Name, partDesc.Namespace, OperationKnownTypes);
                        return serializers [partDesc];
                }
 
index 450f647964ee06ab522826bf434f6ae234454a94..d1e0575a2aca510ebf92ca62fbc4c3897606f21d 100644 (file)
@@ -121,6 +121,7 @@ System.ServiceModel.Description/TypedMessageConverterTest.cs
 System.ServiceModel.Description/WsdlExporterTest.cs
 System.ServiceModel.Description/WsdlImporterTest.cs
 System.ServiceModel.Dispatcher/ActionFilterTest.cs
+System.ServiceModel.Dispatcher/Bug652331Test.cs
 System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs
 System.ServiceModel.Dispatcher/DispatchOperationTest.cs
 System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs
diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug652331Test.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/Bug652331Test.cs
new file mode 100644 (file)
index 0000000..d0e0ea0
--- /dev/null
@@ -0,0 +1,378 @@
+//
+// Authors:
+//     David Straw
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2011 Novell, Inc.  http://www.novell.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Threading;
+using NUnit.Framework;
+
+using WebServiceMoonlightTest.ServiceReference1;
+
+namespace MonoTests.System.ServiceModel.Dispatcher
+{
+       [TestFixture]
+       public class Bug652331Test
+       {
+               [Test]
+               public void Bug652331_2 () // test in one of the comment
+               {
+                       // Init service
+                       ServiceHost serviceHost = new ServiceHost (typeof (Service1), new Uri ("http://localhost:37564/Service1"));
+                       serviceHost.AddServiceEndpoint (typeof (IService1), new BasicHttpBinding (), string.Empty);
+
+                       // Enable metadata exchange (WSDL publishing)
+                       var mexBehavior = new ServiceMetadataBehavior ();
+                       mexBehavior.HttpGetEnabled = true;
+                       serviceHost.Description.Behaviors.Add (mexBehavior);
+                       serviceHost.AddServiceEndpoint (typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
+
+                       serviceHost.Open ();
+
+                       try {
+                               // client
+                               var binding = new BasicHttpBinding ();
+                               var remoteAddress = new EndpointAddress ("http://localhost:37564/Service1");
+                               var client = new Service1Client (binding, remoteAddress);
+
+                               var wait = new ManualResetEvent (false);
+                               client.GetDataCompleted += delegate (object o, GetDataCompletedEventArgs e) {
+                                       if (e.Error != null)
+                                               throw e.Error;
+                                       Assert.AreEqual ("A", ((DataType1) e.Result).Id, "#1");
+                                       wait.Set ();
+                               };
+
+                               client.GetDataAsync ();
+                               if (!wait.WaitOne (TimeSpan.FromSeconds (10)))
+                                       Assert.Fail ("timeout");
+                       } finally {
+                               serviceHost.Close ();
+                       }
+               }
+
+               public class Service1 : IService1
+               {
+                       public object GetData ()
+                       {
+                               return new DataType1 { Id = "A" };
+                       }
+
+                       Func<object> d;
+                       public IAsyncResult BeginGetData (AsyncCallback callback, object state)
+                       {
+                               if (d == null)
+                               d = new Func<object> (GetData);
+                               return d.BeginInvoke (callback, state);
+                       }
+
+                       public object EndGetData (IAsyncResult result)
+                       {
+                               return d.EndInvoke (result);
+                       }
+               }
+       }
+}
+
+// below are part of autogenerated code in comment #1 on bug #652331.
+
+namespace WebServiceMoonlightTest.ServiceReference1 {
+
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="DataType1", Namespace="http://mynamespace")]
+    public partial class DataType1 : object, System.ComponentModel.INotifyPropertyChanged {
+        
+        private string IdField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public string Id {
+            get {
+                return this.IdField;
+            }
+            set {
+                if ((object.ReferenceEquals(this.IdField, value) != true)) {
+                    this.IdField = value;
+                    this.RaisePropertyChanged("Id");
+                }
+            }
+        }
+        
+        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+        
+        protected void RaisePropertyChanged(string propertyName) {
+            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
+            if ((propertyChanged != null)) {
+                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
+            }
+        }
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    [System.ServiceModel.ServiceContractAttribute(Namespace="http://mynamespace", ConfigurationName="ServiceReference1.IService1")]
+[ServiceKnownType (typeof (DataType1))]
+    public interface IService1 {
+        
+        [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://mynamespace/IService1/GetData", ReplyAction="http://mynamespace/IService1/GetDataResponse")]
+        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(WebServiceMoonlightTest.ServiceReference1.DataType1))]
+        System.IAsyncResult BeginGetData(System.AsyncCallback callback, object asyncState);
+        
+        object EndGetData(System.IAsyncResult result);
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    public interface IService1Channel : WebServiceMoonlightTest.ServiceReference1.IService1, System.ServiceModel.IClientChannel {
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    public partial class GetDataCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
+        
+        private object[] results;
+        
+        public GetDataCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
+                base(exception, cancelled, userState) {
+            this.results = results;
+        }
+        
+        public object Result {
+            get {
+                base.RaiseExceptionIfNecessary();
+                return ((object)(this.results[0]));
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    public partial class Service1Client : System.ServiceModel.ClientBase<WebServiceMoonlightTest.ServiceReference1.IService1>, WebServiceMoonlightTest.ServiceReference1.IService1 {
+        
+        private BeginOperationDelegate onBeginGetDataDelegate;
+        
+        private EndOperationDelegate onEndGetDataDelegate;
+        
+        private System.Threading.SendOrPostCallback onGetDataCompletedDelegate;
+        
+        private BeginOperationDelegate onBeginOpenDelegate;
+        
+        private EndOperationDelegate onEndOpenDelegate;
+        
+        private System.Threading.SendOrPostCallback onOpenCompletedDelegate;
+        
+        private BeginOperationDelegate onBeginCloseDelegate;
+        
+        private EndOperationDelegate onEndCloseDelegate;
+        
+        private System.Threading.SendOrPostCallback onCloseCompletedDelegate;
+        
+        public Service1Client() {
+        }
+        
+        public Service1Client(string endpointConfigurationName) : 
+                base(endpointConfigurationName) {
+        }
+        
+        public Service1Client(string endpointConfigurationName, string remoteAddress) : 
+                base(endpointConfigurationName, remoteAddress) {
+        }
+        
+        public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
+                base(endpointConfigurationName, remoteAddress) {
+        }
+        
+        public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
+                base(binding, remoteAddress) {
+        }
+        
+/*
+        public System.Net.CookieContainer CookieContainer {
+            get {
+                System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager>();
+                if ((httpCookieContainerManager != null)) {
+                    return httpCookieContainerManager.CookieContainer;
+                }
+                else {
+                    return null;
+                }
+            }
+            set {
+                System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager>();
+                if ((httpCookieContainerManager != null)) {
+                    httpCookieContainerManager.CookieContainer = value;
+                }
+                else {
+                    throw new System.InvalidOperationException("Unable to set the CookieContainer. Please make sure the binding contains an HttpC" +
+                            "ookieContainerBindingElement.");
+                }
+            }
+        }
+*/
+        
+        public event System.EventHandler<GetDataCompletedEventArgs> GetDataCompleted;
+        
+        public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> OpenCompleted;
+        
+        public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> CloseCompleted;
+        
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+        System.IAsyncResult WebServiceMoonlightTest.ServiceReference1.IService1.BeginGetData(System.AsyncCallback callback, object asyncState) {
+            return base.Channel.BeginGetData(callback, asyncState);
+        }
+        
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+        object WebServiceMoonlightTest.ServiceReference1.IService1.EndGetData(System.IAsyncResult result) {
+            return base.Channel.EndGetData(result);
+        }
+        
+        private System.IAsyncResult OnBeginGetData(object[] inValues, System.AsyncCallback callback, object asyncState) {
+            return ((WebServiceMoonlightTest.ServiceReference1.IService1)(this)).BeginGetData(callback, asyncState);
+        }
+        
+        private object[] OnEndGetData(System.IAsyncResult result) {
+            object retVal = ((WebServiceMoonlightTest.ServiceReference1.IService1)(this)).EndGetData(result);
+            return new object[] {
+                    retVal};
+        }
+        
+        private void OnGetDataCompleted(object state) {
+            if ((this.GetDataCompleted != null)) {
+                InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                this.GetDataCompleted(this, new GetDataCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState));
+            }
+        }
+        
+        public void GetDataAsync() {
+            this.GetDataAsync(null);
+        }
+        
+        public void GetDataAsync(object userState) {
+            if ((this.onBeginGetDataDelegate == null)) {
+                this.onBeginGetDataDelegate = new BeginOperationDelegate(this.OnBeginGetData);
+            }
+            if ((this.onEndGetDataDelegate == null)) {
+                this.onEndGetDataDelegate = new EndOperationDelegate(this.OnEndGetData);
+            }
+            if ((this.onGetDataCompletedDelegate == null)) {
+                this.onGetDataCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnGetDataCompleted);
+            }
+            base.InvokeAsync(this.onBeginGetDataDelegate, null, this.onEndGetDataDelegate, this.onGetDataCompletedDelegate, userState);
+        }
+        
+        private System.IAsyncResult OnBeginOpen(object[] inValues, System.AsyncCallback callback, object asyncState) {
+            return ((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(callback, asyncState);
+        }
+        
+        private object[] OnEndOpen(System.IAsyncResult result) {
+            ((System.ServiceModel.ICommunicationObject)(this)).EndOpen(result);
+            return null;
+        }
+        
+        private void OnOpenCompleted(object state) {
+            if ((this.OpenCompleted != null)) {
+                InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                this.OpenCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState));
+            }
+        }
+        
+        public void OpenAsync() {
+            this.OpenAsync(null);
+        }
+        
+        public void OpenAsync(object userState) {
+            if ((this.onBeginOpenDelegate == null)) {
+                this.onBeginOpenDelegate = new BeginOperationDelegate(this.OnBeginOpen);
+            }
+            if ((this.onEndOpenDelegate == null)) {
+                this.onEndOpenDelegate = new EndOperationDelegate(this.OnEndOpen);
+            }
+            if ((this.onOpenCompletedDelegate == null)) {
+                this.onOpenCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnOpenCompleted);
+            }
+            base.InvokeAsync(this.onBeginOpenDelegate, null, this.onEndOpenDelegate, this.onOpenCompletedDelegate, userState);
+        }
+        
+        private System.IAsyncResult OnBeginClose(object[] inValues, System.AsyncCallback callback, object asyncState) {
+            return ((System.ServiceModel.ICommunicationObject)(this)).BeginClose(callback, asyncState);
+        }
+        
+        private object[] OnEndClose(System.IAsyncResult result) {
+            ((System.ServiceModel.ICommunicationObject)(this)).EndClose(result);
+            return null;
+        }
+        
+        private void OnCloseCompleted(object state) {
+            if ((this.CloseCompleted != null)) {
+                InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+                this.CloseCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState));
+            }
+        }
+        
+        public void CloseAsync() {
+            this.CloseAsync(null);
+        }
+        
+        public void CloseAsync(object userState) {
+            if ((this.onBeginCloseDelegate == null)) {
+                this.onBeginCloseDelegate = new BeginOperationDelegate(this.OnBeginClose);
+            }
+            if ((this.onEndCloseDelegate == null)) {
+                this.onEndCloseDelegate = new EndOperationDelegate(this.OnEndClose);
+            }
+            if ((this.onCloseCompletedDelegate == null)) {
+                this.onCloseCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnCloseCompleted);
+            }
+            base.InvokeAsync(this.onBeginCloseDelegate, null, this.onEndCloseDelegate, this.onCloseCompletedDelegate, userState);
+        }
+        
+/*
+        protected override WebServiceMoonlightTest.ServiceReference1.IService1 CreateChannel() {
+            return new Service1ClientChannel(this);
+        }
+        
+        private class Service1ClientChannel : ChannelBase<WebServiceMoonlightTest.ServiceReference1.IService1>, WebServiceMoonlightTest.ServiceReference1.IService1 {
+            
+            public Service1ClientChannel(System.ServiceModel.ClientBase<WebServiceMoonlightTest.ServiceReference1.IService1> client) : 
+                    base(client) {
+            }
+            
+            public System.IAsyncResult BeginGetData(System.AsyncCallback callback, object asyncState) {
+                object[] _args = new object[0];
+                System.IAsyncResult _result = base.BeginInvoke("GetData", _args, callback, asyncState);
+                return _result;
+            }
+            
+            public object EndGetData(System.IAsyncResult result) {
+                object[] _args = new object[0];
+                object _result = ((object)(base.EndInvoke("GetData", _args, result)));
+                return _result;
+            }
+        }
+*/
+    }
+}