diff --git a/src/System.Private.ServiceModel/tests/Common/Scenarios/Endpoints.cs b/src/System.Private.ServiceModel/tests/Common/Scenarios/Endpoints.cs index b21c7d5090b..1444582732c 100644 --- a/src/System.Private.ServiceModel/tests/Common/Scenarios/Endpoints.cs +++ b/src/System.Private.ServiceModel/tests/Common/Scenarios/Endpoints.cs @@ -128,4 +128,14 @@ public static string Tcp_NoSecurity_DuplexCallback_Address { get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackResource"); } } + + public static string Tcp_NoSecurity_DataContractDuplexCallback_Address + { + get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackDataContractComplexTypeResource"); } + } + + public static string Tcp_NoSecurity_XmlDuplexCallback_Address + { + get { return BridgeClient.GetResourceAddress("WcfService.TestResources.DuplexCallbackXmlComplexTypeResource"); } + } } diff --git a/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestTypes.cs b/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestTypes.cs index bebc1a0fcb6..93f9822f1b3 100644 --- a/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestTypes.cs +++ b/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestTypes.cs @@ -688,6 +688,61 @@ public string StringValue } } +// This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsDataContractComplexType +// It tests a narrow scenario that returns a DataContract attributed type in the callback method that is not known by the ServiceContract attributed interface +// This test is designed to make sure the NET Native toolchain creates the needed serializer +[DataContract(Namespace = "http://www.contoso.com/wcfnamespace")] +public class ComplexCompositeTypeDuplexCallbackOnly : IEquatable +{ + private Guid _guidValue; + + [DataMember] + public Guid GuidValue + { + get { return _guidValue; } + set { _guidValue = value; } + } + + public bool Equals(ComplexCompositeTypeDuplexCallbackOnly other) + { + if (other == null) { return false; } + if (object.ReferenceEquals(this, other)) { return true; } + + if (_guidValue != other._guidValue) { return false; } + + return true; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("GuidValue: " + _guidValue); + + return sb.ToString(); + } +} + +// This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsXmlComplexType +// It tests a narrow scenario that returns an Xml attributed type in the callback method that is not known by the ServiceContract attributed interface +// This test is designed to make sure the NET Native toolchain creates the needed serializer +public class XmlCompositeTypeDuplexCallbackOnly +{ + private bool _boolValue = true; + private string _stringValue = "Hello "; + + public bool BoolValue + { + get { return _boolValue; } + set { _boolValue = value; } + } + + public string StringValue + { + get { return _stringValue; } + set { _stringValue = value; } + } +} + public class DuplexTaskReturnServiceCallback : IWcfDuplexTaskReturnCallback { private bool _wrapExceptionInTask; @@ -772,13 +827,17 @@ public MyDuplexClientBase(InstanceContext callbackInstance, Binding binding, End } } -public class WcfDuplexServiceCallback : IWcfDuplexServiceCallback +public class WcfDuplexServiceCallback : IWcfDuplexServiceCallback, IWcfDuplexService_DataContract_Callback, IWcfDuplexService_Xml_Callback { private TaskCompletionSource _tcs; + private TaskCompletionSource _xml_tcs; + private TaskCompletionSource _datacontract_tcs; public WcfDuplexServiceCallback() { _tcs = new TaskCompletionSource(); + _xml_tcs = new TaskCompletionSource(); + _datacontract_tcs = new TaskCompletionSource(); } public Guid CallbackGuid @@ -793,6 +852,30 @@ public Guid CallbackGuid } } + public XmlCompositeTypeDuplexCallbackOnly XmlCallbackGuid + { + get + { + if (_xml_tcs.Task.Wait(ScenarioTestHelpers.TestTimeout)) + { + return _xml_tcs.Task.Result; + } + throw new TimeoutException(string.Format("Not completed within the alloted time of {0}", ScenarioTestHelpers.TestTimeout)); + } + } + + public ComplexCompositeTypeDuplexCallbackOnly DataContractCallbackGuid + { + get + { + if (_datacontract_tcs.Task.Wait(ScenarioTestHelpers.TestTimeout)) + { + return _datacontract_tcs.Task.Result; + } + throw new TimeoutException(string.Format("Not completed within the alloted time of {0}", ScenarioTestHelpers.TestTimeout)); + } + } + public void OnPingCallback(Guid guid) { // Set the result in an async task with a 100ms delay to prevent a race condition @@ -803,4 +886,26 @@ public void OnPingCallback(Guid guid) _tcs.SetResult(guid); }); } + + public void OnXmlPingCallback(XmlCompositeTypeDuplexCallbackOnly xmlCompositeType) + { + // Set the result in an async task with a 100ms delay to prevent a race condition + // where the OnPingCallback hasn't sent the reply to the server before the channel is closed. + Task.Run(async () => + { + await Task.Delay(100); + _xml_tcs.SetResult(xmlCompositeType); + }); + } + + public void OnDataContractPingCallback(ComplexCompositeTypeDuplexCallbackOnly dataContractCompositeType) + { + // Set the result in an async task with a 100ms delay to prevent a race condition + // where the OnPingCallback hasn't sent the reply to the server before the channel is closed. + Task.Run(async () => + { + await Task.Delay(100); + _datacontract_tcs.SetResult(dataContractCompositeType); + }); + } } diff --git a/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs b/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs index e8dfa8c3c7d..29b9ccc3a89 100644 --- a/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs +++ b/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs @@ -275,3 +275,33 @@ public interface IWcfDuplexTaskReturnCallback Action = "http://tempuri.org/IWcfDuplexTaskReturnCallback/ServicePingFaultCallbackFaultDetailFault")] Task ServicePingFaultCallback(Guid guid); } + +// ******************************************************************************** + +[ServiceContract(CallbackContract = typeof(IWcfDuplexService_DataContract_Callback))] +public interface IWcfDuplexService_DataContract +{ + [OperationContract] + void Ping_DataContract(Guid guid); +} + +public interface IWcfDuplexService_DataContract_Callback +{ + [OperationContract] + void OnDataContractPingCallback(ComplexCompositeTypeDuplexCallbackOnly complexCompositeType); +} + +// ******************************************************************************** + +[ServiceContract(CallbackContract = typeof(IWcfDuplexService_Xml_Callback))] +public interface IWcfDuplexService_Xml +{ + [OperationContract] + void Ping_Xml(Guid guid); +} + +public interface IWcfDuplexService_Xml_Callback +{ + [OperationContract, XmlSerializerFormat] + void OnXmlPingCallback(XmlCompositeTypeDuplexCallbackOnly xmlCompositeType); +} diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/DataContractTests.cs b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/DataContractTests.cs index d6e196bf4ca..2dcfcdf8219 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/DataContractTests.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/DataContractTests.cs @@ -4,6 +4,7 @@ using System; using System.ServiceModel; using System.ServiceModel.Channels; +using TestTypes; using System.Text; using Xunit; @@ -51,4 +52,81 @@ public static void CustomBinding_DefaultSettings_Echo_RoundTrips_DataContract() Assert.True(errorBuilder.Length == 0, errorBuilder.ToString()); } + + // Verify that a callback contract correctly returns a complex type when this type is not part of the contract with the ServiceContract attribute. + [Fact] + [OuterLoop] + public static void NetTcpBinding_DuplexCallback_ReturnsDataContractComplexType() + { + DuplexChannelFactory factory = null; + NetTcpBinding binding = null; + WcfDuplexServiceCallback callbackService = null; + InstanceContext context = null; + IWcfDuplexService_DataContract serviceProxy = null; + Guid guid = Guid.NewGuid(); + + try + { + binding = new NetTcpBinding(); + binding.Security.Mode = SecurityMode.None; + + callbackService = new WcfDuplexServiceCallback(); + context = new InstanceContext(callbackService); + + factory = new DuplexChannelFactory(context, binding, new EndpointAddress(Endpoints.Tcp_NoSecurity_DataContractDuplexCallback_Address)); + serviceProxy = factory.CreateChannel(); + + serviceProxy.Ping_DataContract(guid); + ComplexCompositeTypeDuplexCallbackOnly returnedType = callbackService.DataContractCallbackGuid; + + // validate response + Assert.True((guid == returnedType.GuidValue), String.Format("The Guid sent was not the same as the Guid returned.\nSent: {0}\nReturned: {1}", guid, returnedType.GuidValue)); + + ((ICommunicationObject)serviceProxy).Close(); + factory.Close(); + } + finally + { + ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory); + } + } + + // Verify that a callback contract correctly returns a complex type using Xml instead of DataContract when this type is not part of the contract with the ServiceContract attribute. + [Fact] + [OuterLoop] + [ActiveIssue(292)] + public static void NetTcpBinding_DuplexCallback_ReturnsXmlComplexType() + { + DuplexChannelFactory factory = null; + NetTcpBinding binding = null; + WcfDuplexServiceCallback callbackService = null; + InstanceContext context = null; + IWcfDuplexService_Xml serviceProxy = null; + Guid guid = Guid.NewGuid(); + + try + { + binding = new NetTcpBinding(); + binding.Security.Mode = SecurityMode.None; + + callbackService = new WcfDuplexServiceCallback(); + context = new InstanceContext(callbackService); + + factory = new DuplexChannelFactory(context, binding, new EndpointAddress(Endpoints.Tcp_NoSecurity_XmlDuplexCallback_Address)); + serviceProxy = factory.CreateChannel(); + + serviceProxy.Ping_Xml(guid); + XmlCompositeTypeDuplexCallbackOnly returnedType = callbackService.XmlCallbackGuid; + + // validate response + Assert.True((guid.ToString() == returnedType.StringValue), String.Format("The Guid to string value sent was not the same as what was returned.\nSent: {0}\nReturned: {1}", guid.ToString(), returnedType.StringValue)); + + ((ICommunicationObject)serviceProxy).Close(); + factory.Close(); + } + finally + { + ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory); + } + } } diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.json b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.json index 026fa5e0d59..0cd9f1e3bec 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.json +++ b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.json @@ -1,7 +1,9 @@ { "dependencies": { "System.Reflection.Emit.Lightweight": "4.0.0", + "System.ServiceModel.Duplex": "4.0.0-beta-*", "System.ServiceModel.Http": "4.0.10-beta-*", + "System.ServiceModel.NetTcp": "4.0.0-beta-*", "System.ServiceModel.Primitives": "4.0.0-beta-*", "xunit": "2.1.0-beta3-*", "xunit.netcore.extensions": "1.0.0-prerelease-*" diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.lock.json b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.lock.json index d5ba47cb3c8..0ff58304450 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.lock.json +++ b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Data/project.lock.json @@ -874,6 +874,17 @@ "lib/DNXCore50/System.Security.SecureString.dll": {} } }, + "System.ServiceModel.Duplex/4.0.0-beta-23127": { + "dependencies": { + "System.Private.ServiceModel": "4.0.0-beta-23127" + }, + "compile": { + "ref/dotnet/System.ServiceModel.Duplex.dll": {} + }, + "runtime": { + "lib/DNXCore50/System.ServiceModel.Duplex.dll": {} + } + }, "System.ServiceModel.Http/4.0.10-beta-23127": { "dependencies": { "System.Runtime": "4.0.20-beta-23127", @@ -886,6 +897,17 @@ "lib/DNXCore50/System.ServiceModel.Http.dll": {} } }, + "System.ServiceModel.NetTcp/4.0.0-beta-23127": { + "dependencies": { + "System.Private.ServiceModel": "4.0.0-beta-23127" + }, + "compile": { + "ref/dotnet/System.ServiceModel.NetTcp.dll": {} + }, + "runtime": { + "lib/DNXCore50/System.ServiceModel.NetTcp.dll": {} + } + }, "System.ServiceModel.Primitives/4.0.0-beta-23127": { "dependencies": { "System.Private.ServiceModel": "4.0.0-beta-23127" @@ -2782,6 +2804,34 @@ "ref/xamarinmac20/_._" ] }, + "System.ServiceModel.Duplex/4.0.0-beta-23127": { + "serviceable": true, + "sha512": "rUMhAc+OMl535nl0gPCItlZkEHTqJhp+Moyo7ma21KVHpb1JfbZS/uXh8ayHW81THQBEKEEPUqMCX3YWQiXPYQ==", + "files": [ + "System.ServiceModel.Duplex.4.0.0-beta-23127.nupkg", + "System.ServiceModel.Duplex.4.0.0-beta-23127.nupkg.sha512", + "System.ServiceModel.Duplex.nuspec", + "lib/DNXCore50/System.ServiceModel.Duplex.dll", + "lib/net45/_._", + "lib/netcore50/System.ServiceModel.Duplex.dll", + "lib/win8/_._", + "ref/dotnet/System.ServiceModel.Duplex.dll", + "ref/dotnet/System.ServiceModel.Duplex.xml", + "ref/dotnet/de/System.ServiceModel.Duplex.xml", + "ref/dotnet/es/System.ServiceModel.Duplex.xml", + "ref/dotnet/fr/System.ServiceModel.Duplex.xml", + "ref/dotnet/it/System.ServiceModel.Duplex.xml", + "ref/dotnet/ja/System.ServiceModel.Duplex.xml", + "ref/dotnet/ko/System.ServiceModel.Duplex.xml", + "ref/dotnet/ru/System.ServiceModel.Duplex.xml", + "ref/dotnet/zh-hans/System.ServiceModel.Duplex.xml", + "ref/dotnet/zh-hant/System.ServiceModel.Duplex.xml", + "ref/net45/_._", + "ref/netcore50/System.ServiceModel.Duplex.dll", + "ref/netcore50/System.ServiceModel.Duplex.xml", + "ref/win8/_._" + ] + }, "System.ServiceModel.Http/4.0.10-beta-23127": { "serviceable": true, "sha512": "oCqqO9jjhcXxe8Csgd6J1jraz5Nmj6uz2tqqc4f7CB94VKLFUVn/BmzhcySVewZ4PxBOR8HuPHpPgwm537BbUA==", @@ -2814,6 +2864,34 @@ "ref/xamarinmac20/_._" ] }, + "System.ServiceModel.NetTcp/4.0.0-beta-23127": { + "serviceable": true, + "sha512": "70Yq+IATcueKOnUgafuF57T0gbJgOFqIyciD/05hVDuOpcAFBzc47qwSfrhQvIsBRiGtZNzkdEHHERWAR1mlQQ==", + "files": [ + "System.ServiceModel.NetTcp.4.0.0-beta-23127.nupkg", + "System.ServiceModel.NetTcp.4.0.0-beta-23127.nupkg.sha512", + "System.ServiceModel.NetTcp.nuspec", + "lib/DNXCore50/System.ServiceModel.NetTcp.dll", + "lib/net45/_._", + "lib/netcore50/System.ServiceModel.NetTcp.dll", + "lib/win8/_._", + "ref/dotnet/System.ServiceModel.NetTcp.dll", + "ref/dotnet/System.ServiceModel.NetTcp.xml", + "ref/dotnet/de/System.ServiceModel.NetTcp.xml", + "ref/dotnet/es/System.ServiceModel.NetTcp.xml", + "ref/dotnet/fr/System.ServiceModel.NetTcp.xml", + "ref/dotnet/it/System.ServiceModel.NetTcp.xml", + "ref/dotnet/ja/System.ServiceModel.NetTcp.xml", + "ref/dotnet/ko/System.ServiceModel.NetTcp.xml", + "ref/dotnet/ru/System.ServiceModel.NetTcp.xml", + "ref/dotnet/zh-hans/System.ServiceModel.NetTcp.xml", + "ref/dotnet/zh-hant/System.ServiceModel.NetTcp.xml", + "ref/net45/_._", + "ref/netcore50/System.ServiceModel.NetTcp.dll", + "ref/netcore50/System.ServiceModel.NetTcp.xml", + "ref/win8/_._" + ] + }, "System.ServiceModel.Primitives/4.0.0-beta-23127": { "serviceable": true, "sha512": "+p6lz5Hir8RVNeUjxh0USWqHAyDN64cG1UokOKCSswcey7WQUWnAvniO6GsXtdAAnTmXaWEy86cnrzk/Fdn/3A==", @@ -3298,7 +3376,9 @@ "projectFileDependencyGroups": { "": [ "System.Reflection.Emit.Lightweight >= 4.0.0", + "System.ServiceModel.Duplex >= 4.0.0-beta-*", "System.ServiceModel.Http >= 4.0.10-beta-*", + "System.ServiceModel.NetTcp >= 4.0.0-beta-*", "System.ServiceModel.Primitives >= 4.0.0-beta-*", "xunit >= 2.1.0-beta3-*", "xunit.netcore.extensions >= 1.0.0-prerelease-*" diff --git a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/ComplexCompositeType.cs b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/ComplexCompositeType.cs index 3a25e672a49..c455d79c6a1 100644 --- a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/ComplexCompositeType.cs +++ b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/ComplexCompositeType.cs @@ -8,7 +8,7 @@ namespace WcfService { [DataContract(Namespace = "http://www.contoso.com/wcfnamespace")] - internal class ComplexCompositeType : IEquatable + public class ComplexCompositeType : IEquatable { private bool _boolValue; private char _charValue; @@ -238,4 +238,38 @@ public override string ToString() return sb.ToString(); } } + + // This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsDataContractComplexType + // It tests a narrow scenario that returns a DataContract attributed type in the callback method that is not known by the ServiceContract attributed interface + // This test is designed to make sure the NET Native toolchain creates the needed serializer + [DataContract(Namespace = "http://www.contoso.com/wcfnamespace")] + public class ComplexCompositeTypeDuplexCallbackOnly : IEquatable + { + private Guid _guidValue; + + [DataMember] + public Guid GuidValue + { + get { return _guidValue; } + set { _guidValue = value; } + } + + public bool Equals(ComplexCompositeTypeDuplexCallbackOnly other) + { + if (other == null) { return false; } + if (object.ReferenceEquals(this, other)) { return true; } + + if (_guidValue != other._guidValue) { return false; } + + return true; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("GuidValue: " + _guidValue); + + return sb.ToString(); + } + } } diff --git a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/CompositeType.cs b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/CompositeType.cs index fdb187814d2..15d926f0889 100644 --- a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/CompositeType.cs +++ b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/CompositeType.cs @@ -43,4 +43,25 @@ public string StringValue set { _stringValue = value; } } } + + // This type should only be used by test Contract.DataContractTests.NetTcpBinding_DuplexCallback_ReturnsXmlComplexType + // It tests a narrow scenario that returns an Xml attributed type in the callback method that is not known by the ServiceContract attributed interface + // This test is designed to make sure the NET Native toolchain creates the needed serializer + public class XmlCompositeTypeDuplexCallbackOnly + { + private bool _boolValue = true; + private string _stringValue = "Hello "; + + public bool BoolValue + { + get { return _boolValue; } + set { _boolValue = value; } + } + + public string StringValue + { + get { return _stringValue; } + set { _stringValue = value; } + } + } } diff --git a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/IWcfDuplexService.cs b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/IWcfDuplexService.cs index 0af7736b2d0..b0dd6a2bfa4 100644 --- a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/IWcfDuplexService.cs +++ b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/IWcfDuplexService.cs @@ -55,4 +55,34 @@ public interface IWcfDuplexTaskReturnCallback Action = "http://tempuri.org/IWcfDuplexTaskReturnCallback/ServicePingFaultCallbackFaultDetailFault")] Task ServicePingFaultCallback(Guid guid); } + + // ******************************************************************************** + + [ServiceContract(CallbackContract = typeof(IWcfDuplexService_Xml_Callback))] + public interface IWcfDuplexService_Xml + { + [OperationContract] + void Ping_Xml(Guid guid); + } + + public interface IWcfDuplexService_Xml_Callback + { + [OperationContract, XmlSerializerFormat] + void OnXmlPingCallback(XmlCompositeTypeDuplexCallbackOnly xmlCompositeType); + } + + // ******************************************************************************** + + [ServiceContract(CallbackContract = typeof(IWcfDuplexService_DataContract_Callback))] + public interface IWcfDuplexService_DataContract + { + [OperationContract] + void Ping_DataContract(Guid guid); + } + + public interface IWcfDuplexService_DataContract_Callback + { + [OperationContract] + void OnDataContractPingCallback(ComplexCompositeTypeDuplexCallbackOnly complexCompositeType); + } } diff --git a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/TestResources/DuplexResources.cs b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/TestResources/DuplexResources.cs index 620d6f7a73c..b05af4bebb5 100644 --- a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/TestResources/DuplexResources.cs +++ b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/TestResources/DuplexResources.cs @@ -57,4 +57,38 @@ protected override Binding GetBinding() return new NetTcpBinding(SecurityMode.None) { PortSharingEnabled = false }; } } + + internal class DuplexCallbackDataContractComplexTypeResource : EndpointResource + { + protected override string Protocol { get { return BaseAddressResource.Tcp; } } + + protected override int GetPort(ResourceRequestContext context) + { + return context.BridgeConfiguration.BridgeTcpPort + 4; + } + + protected override string Address { get { return "tcp-nosecurity-callback"; } } + + protected override Binding GetBinding() + { + return new NetTcpBinding(SecurityMode.None) { PortSharingEnabled = false }; + } + } + + internal class DuplexCallbackXmlComplexTypeResource : EndpointResource + { + protected override string Protocol { get { return BaseAddressResource.Tcp; } } + + protected override int GetPort(ResourceRequestContext context) + { + return context.BridgeConfiguration.BridgeTcpPort + 5; + } + + protected override string Address { get { return "tcp-nosecurity-callback"; } } + + protected override Binding GetBinding() + { + return new NetTcpBinding(SecurityMode.None) { PortSharingEnabled = false }; + } + } } diff --git a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/WcfDuplexService.cs b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/WcfDuplexService.cs index b0a2826448e..e9443fe179b 100644 --- a/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/WcfDuplexService.cs +++ b/src/System.Private.ServiceModel/tools/test/SelfHostWcfService/WcfDuplexService.cs @@ -7,15 +7,39 @@ namespace WcfService { - internal class WcfDuplexService : IWcfDuplexService + internal class WcfDuplexService : IWcfDuplexService, IWcfDuplexService_DataContract, IWcfDuplexService_Xml { public static IWcfDuplexServiceCallback callback; + public static IWcfDuplexService_DataContract_Callback dc_callback; + public static IWcfDuplexService_Xml_Callback xml_callback; + public void Ping(Guid guid) { callback = OperationContext.Current.GetCallbackChannel(); // Schedule the callback on another thread to avoid reentrancy. Task.Run(() => callback.OnPingCallback(guid)); } + + public void Ping_DataContract(Guid guid) + { + dc_callback = OperationContext.Current.GetCallbackChannel(); + + ComplexCompositeTypeDuplexCallbackOnly complexCompositeType = new ComplexCompositeTypeDuplexCallbackOnly(); + complexCompositeType.GuidValue = guid; + + // Schedule the callback on another thread to avoid reentrancy. + Task.Run(() => dc_callback.OnDataContractPingCallback(complexCompositeType)); + } + + public void Ping_Xml(Guid guid) + { + xml_callback = OperationContext.Current.GetCallbackChannel(); + XmlCompositeTypeDuplexCallbackOnly xmlCompositeType = new XmlCompositeTypeDuplexCallbackOnly(); + xmlCompositeType.StringValue = guid.ToString(); + + // Schedule the callback on another thread to avoid reentrancy. + Task.Run(() => xml_callback.OnXmlPingCallback(xmlCompositeType)); + } } [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]