瀏覽代碼

Request-reply channel factory should not reject one-way operation. It should just ignore the void reply.

Atsushi Eno 15 年之前
父節點
當前提交
dfe40a5745

+ 4 - 2
mcs/class/System.ServiceModel/System.ServiceModel/ChannelFactory.cs

@@ -198,7 +198,9 @@ namespace System.ServiceModel
 						return Endpoint.Binding.BuildChannelFactory<IOutputChannel> (pl);
 					break;
 				}
-			} else {
+			}
+			// both OneWay and non-OneWay contracts fall into here.
+			{
 				switch (Endpoint.Contract.SessionMode) {
 				case SessionMode.Required:
 					if (Endpoint.Binding.CanBuildChannelFactory<IRequestSessionChannel> (pl))
@@ -216,7 +218,7 @@ namespace System.ServiceModel
 					break;
 				}
 			}
-			throw new InvalidOperationException ("The binding does not support any of the channel types that the contract allows.");
+			throw new InvalidOperationException (String.Format ("The binding does not support any of the channel types that the contract '{0}' allows.", Endpoint.Contract.Name));
 		}
 
 		BindingParameterCollection CreateBindingParameters ()

+ 4 - 1
mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs

@@ -548,7 +548,10 @@ namespace System.ServiceModel.MonoInternal
 
 		internal void Send (Message msg, TimeSpan timeout)
 		{
-			OutputChannel.Send (msg, timeout);
+			if (OutputChannel != null)
+				OutputChannel.Send (msg, timeout);
+			else
+				RequestChannel.Request (msg, timeout); // and ignore returned message.
 		}
 
 		internal IAsyncResult BeginSend (Message msg, TimeSpan timeout, AsyncCallback callback, object state)

+ 39 - 0
mcs/class/System.ServiceModel/Test/System.ServiceModel/ChannelFactory_1Test.cs

@@ -32,6 +32,7 @@ using System.Runtime.Serialization;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
+using System.Threading;
 using System.Xml;
 using System.Xml.Serialization;
 using MonoTests.System.ServiceModel.Channels;
@@ -476,6 +477,27 @@ namespace MonoTests.System.ServiceModel
 			Assert.AreEqual ("callArg", res.resMsg.val, "#3");
 		}
 
+		[Test]
+		public void OneWayOperationWithRequestReplyChannel ()
+		{
+			var host = new ServiceHost (typeof (OneWayService));
+			host.AddServiceEndpoint (typeof (IOneWayService),
+				new BasicHttpBinding (),
+				new Uri ("http://localhost:8080"));
+			host.Open ();
+			try {
+				var cf = new ChannelFactory<IOneWayService> (
+					new BasicHttpBinding (),
+					new EndpointAddress ("http://localhost:8080"));
+				var ch = cf.CreateChannel ();
+				ch.GiveMessage ("test");
+				
+				Assert.IsTrue (OneWayService.WaitHandle.WaitOne (TimeSpan.FromSeconds (5)), "#1");
+			} finally {
+				host.Close ();
+			}
+		}
+
 		[ServiceContract]
 		public interface ITestService
 		{
@@ -522,6 +544,23 @@ namespace MonoTests.System.ServiceModel
 			TestResult FooComplexMC (TestMessage arg1);
 		}
 
+		[ServiceContract]
+		public interface IOneWayService
+		{
+			[OperationContract (IsOneWay = true)]
+			void GiveMessage (string input);
+		}
+
+		public class OneWayService : IOneWayService
+		{
+			public static ManualResetEvent WaitHandle = new ManualResetEvent (false);
+
+			public void GiveMessage (string input)
+			{
+				WaitHandle.Set ();
+			}
+		}
+
 		public enum FooColor { Red = 1, Green, Blue }
 
 		[DataContract]