Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose IErrorHandler and add test case. #5593

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,11 @@ public static string DuplexCallbackDebugBehavior_Address
{
get { return GetEndpointAddress("DuplexCallbackDebugBehavior.svc/tcp", protocol: "net.tcp"); }
}

public static string DuplexCallbackErrorHandler_Address
{
get { return GetEndpointAddress("DuplexCallbackErrorHandler.svc/tcp", protocol: "net.tcp"); }
}
#endregion net.tcp Addresses

#region net.pipe Addresses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -287,6 +288,11 @@ public static void Run(Func<Task> asyncMethod)
}
}

[DataContract]
public class CustomMessage
{
}

[DataContract(Namespace = "http://www.contoso.com/wcfnamespace")]
public class CompositeType
{
Expand Down Expand Up @@ -705,6 +711,53 @@ public void ReplyThrow(string input)
}
}

[CallbackBehavior(UseSynchronizationContext = false)]
public class WcfDuplexService_CallbackErrorHandler_Callback : IWcfDuplexService_CallbackErrorHandler_Callback, IEndpointBehavior, IErrorHandler
{
public void ReplyThrow(string input)
{
throw new FaultException<ArgumentException>(new ArgumentException());
}

void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
return;
}

void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(this);
}

void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
return;
}

void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
{
return;
}

#region IErrorHandler Members
public bool HandleError(Exception error)
{
return true;
}

public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
{
if (error is FaultException<ArgumentException>)
{
//overriding the given fault to CustomMessage fault
var faultObj = new FaultException<CustomMessage>(new CustomMessage(), "custom fault reason", new FaultCode("custom fault code"));
MessageFault fault = faultObj.CreateMessageFault();
msg = Message.CreateMessage(version, fault, "http://tempuri.org/IWcfDuplexService_CallbackErrorHandler/ReplyThrowCustomMessageFault");
}
}
#endregion
}

public class DuplexTaskReturnServiceCallback : IWcfDuplexTaskReturnCallback
{
private bool _wrapExceptionInTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,19 @@ public interface IWcfDuplexService_CallbackDebugBehavior_Callback
void ReplyThrow(string input);
}

[ServiceContract(CallbackContract = typeof(IWcfDuplexService_CallbackErrorHandler_Callback))]
public interface IWcfDuplexService_CallbackErrorHandler
{
[OperationContract]
bool Hello(string greeting);
}

public interface IWcfDuplexService_CallbackErrorHandler_Callback
{
[OperationContract]
void ReplyThrow(string input);
}

[ServiceContract(CallbackContract = typeof(IWcfDuplexTaskReturnCallback))]
public interface IWcfDuplexTaskReturnService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


using System.ServiceModel;
using Infrastructure.Common;
using Xunit;

public partial class CallbackErrorHandlerTests : ConditionalWcfTest
{
[WcfFact]
public static void DuplexCallbackErrorHandlerTest()
{
bool result;
InstanceContext context;
string testString="";
NetTcpBinding binding;
EndpointAddress endpointAddress;
DuplexChannelFactory<IWcfDuplexService_CallbackErrorHandler> factory;
IWcfDuplexService_CallbackErrorHandler serviceProxy;
WcfDuplexService_CallbackErrorHandler_Callback callbackService;

// *** SETUP *** \\
binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
callbackService = new WcfDuplexService_CallbackErrorHandler_Callback();
context = new InstanceContext(callbackService);
endpointAddress = new EndpointAddress(Endpoints.DuplexCallbackErrorHandler_Address);
factory = new DuplexChannelFactory<IWcfDuplexService_CallbackErrorHandler>(context, binding, endpointAddress);
serviceProxy = factory.CreateChannel();

try
{
// *** EXECUTE *** \\
result = serviceProxy.Hello(testString);

// *** CLEANUP *** \\
((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}

// *** ADDITIONAL VALIDATION *** \\
Assert.True(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,8 @@ public PingEncodedRequest(string pinginfo)
this.Pinginfo = pinginfo;
}
}

[DataContract]
public class CustomMessage
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,18 @@ public interface IWcfDuplexService_CallbackDebugBehavior_Callback
[OperationContract]
void ReplyThrow(string input);
}

[ServiceContract(CallbackContract = typeof(IWcfDuplexService_CallbackErrorHandler_Callback))]
public interface IWcfDuplexService_CallbackErrorHandler
{
[OperationContract]
bool Hello(string greeting);
}

public interface IWcfDuplexService_CallbackErrorHandler_Callback
{
[OperationContract]
[FaultContract(typeof(CustomMessage))]
void ReplyThrow(string input);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,37 @@ public IWcfDuplexService_CallbackDebugBehavior_Callback Callback
}
}
}

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WcfDuplexService_CallbackErrorHandler : IWcfDuplexService_CallbackErrorHandler
{
public bool Hello(string greeting)
{
bool result = false;
try
{
Callback.ReplyThrow(greeting);
}
catch (FaultException<CustomMessage> fex)
{
if(fex.Message.Equals("custom fault reason") && fex.Code.Name.Equals("custom fault code"))
{
result = true;
}
}
catch (Exception)
{
}

return result;
}

public IWcfDuplexService_CallbackErrorHandler_Callback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel<IWcfDuplexService_CallbackErrorHandler_Callback>();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,20 @@ public DuplexCallbackDebugBahaviorServiceHost(params Uri[] baseAddresses)
{
}
}

[TestServiceDefinition(Schema = ServiceSchema.NETTCP, BasePath = "DuplexCallbackErrorHandler.svc")]
public class DuplexCallbackErrorHandlerServiceHost : TestServiceHostBase<IWcfDuplexService_CallbackErrorHandler>
{
protected override string Address { get { return "tcp"; } }

protected override Binding GetBinding()
{
return new NetTcpBinding(SecurityMode.None) { PortSharingEnabled = false };
}

public DuplexCallbackErrorHandlerServiceHost(params Uri[] baseAddresses)
: base(typeof(WcfDuplexService_CallbackErrorHandler), baseAddresses)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,7 @@ internal ClientRuntime() { }
public System.Type ContractClientType { get { return default; } set { } }
public string ContractName { get { return default; } }
public string ContractNamespace { get { return default; } }
internal bool EnableFaults { get { return default; } set { } }
public System.Collections.Generic.SynchronizedCollection<IInteractiveChannelInitializer> InteractiveChannelInitializers { get { return default; } }
public bool ManualAddressing { get { return default; } set { } }
public int MaxFaultSize { get { return default; } set { } }
Expand Down Expand Up @@ -1862,6 +1863,7 @@ public partial class ChannelDispatcher
{
internal ChannelDispatcher() { }
public bool IncludeExceptionDetailInFaults { get { return default; } set { } }
public Collection<IErrorHandler> ErrorHandlers { get { return default; } }
}
public partial class EndpointDispatcher
{
Expand Down Expand Up @@ -1907,6 +1909,11 @@ public partial interface IParameterInspector
void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState);
object BeforeCall(string operationName, object[] inputs);
}
public interface IErrorHandler
{
void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault);
bool HandleError(Exception error);
}
}

namespace System.ServiceModel.Security
Expand Down
Loading