23801

WCF FaultContract Fails with NamedPipe

Question:

I have a simple IPC mechanism that uses WCF and named pipes. My goal is to propagate exception details (including the stacktrace) to the client for logging purposes (the rest of the application logging is located on the client).

If I use the following code I am able to catch FaultException<Exception> on the client and see exception details:

Contract:

[ServiceContract] public interface IService { [OperationContract] [FaultContract(typeof(Exception))] void DoSomething(); }

Implementation:

public class Service : IService { public void DoSomething() { try { ThisWillThrowAnException(); } catch (Exception e) { throw new FaultException<Exception>(e); } } }

Client:

public void CallServer() { try { proxy.DoSomething(); } catch (FaultException<Exception> e) { Console.WriteLine("Caught fault exception!"); } }

This works fine and I see the message printed on the console. However, if I want to use my own derived exception instead of the base Exception class, it fails.

Custom Exception:

[Serializable] public class MyException : Exception { public MyException () { } public MyException (string message) : base(message) { } public MyException (string message, Exception inner) : base(message, inner) { } protected MyException ( SerializationInfo info, StreamingContext context) : base(info, context) { } }

Change the FaultContract on IService.DoSomething to

typeof(MyException).

Change the throw clause in Service to

new FaultException<MyException>(new MyException(e.Message, e);

Change the catch clause in the client to

catch (FaultException<MyException> e)

When I execute this, a CommunicationException is caught on the client with the error: <em>System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).</em>

The MyException class is in a shared library available to both the client and server.

This question is very similar to <a href="https://stackoverflow.com/questions/220401/how-do-you-configure-wcf-to-support-faultcontracts-where-both-the-host-and-client" rel="nofollow">this question</a>, but that did not help me.

Answer1:

I resolved this by writing my own fault DataContract which contained a serialized list of StackFrames.

Apparently this MSDN article is not exactly accurate?

<a href="http://msdn.microsoft.com/en-us/library/ff649840.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ff649840.aspx</a>

[DataContract] public class MyFault { [DataMember] public string Message { get; set; } [DataMember] public IList<SerializableMiniStackFrame> StackTrace { get; set; } public static MyFault CreateFault(Exception e) { MyFault fault = new MyFault(); fault.Message = e.Message; fault.InitTrace(e); return fault; } /// <summary> /// Initializes the stack trace based on when the inner exception was thrown. /// </summary> /// <param name="inner">The inner exception.</param> private void InitTrace(Exception inner) { StackTrace trace = new StackTrace(inner, true); InitTrace(trace); } /// <summary> /// Initializes the internal serializable stack frames based on the given /// stack trace. /// </summary> /// <param name="stackTrace">The stack trace.</param> private void InitTrace(StackTrace stackTrace) { // Create a new list of serializable frames. this.StackTrace = new List<SerializableMiniStackFrame>(); // Iterate over each frame in the stack trace. foreach (StackFrame frame in stackTrace.GetFrames()) { string type = ""; Type declaringType = frame.GetMethod().DeclaringType; if (null != declaringType) { type = declaringType.FullName; } MethodBase method = frame.GetMethod(); string methodName = method.Name; string parameters = string.Empty; string delimiter = string.Empty; foreach (ParameterInfo parameter in method.GetParameters()) { parameters += string.Format("{0}{1} {2}", delimiter, parameter.ParameterType.Name, parameter.Name); delimiter = ", "; } string file = Path.GetFileName(frame.GetFileName()); int line = frame.GetFileLineNumber(); // Create a serializable frame and add it to the list. SerializableMiniStackFrame miniFrame = new SerializableMiniStackFrame(type, methodName, parameters, file, line); this.StackTrace.Add(miniFrame); } } } /// <summary> /// This class encapsulates basic stack frame information into a serializable /// object. /// </summary> [DataContract] public class SerializableMiniStackFrame { public SerializableMiniStackFrame() { } public SerializableMiniStackFrame(string type, string method, string parameters, string file, int line) { this.Type = type; this.Method = method; this.Parameters = parameters; this.File = file; this.Line = line; } [DataMember] public string Type { get; set; } [DataMember] public string Method { get; set; } [DataMember] public string Parameters { get; set; } [DataMember] public string File { get; set; } [DataMember] public int Line { get; set; } }

Recommend

  • Does derived class' member functions inherit virtualness from base class?
  • What is the Performance, Safety, and Alignment of a Data member hidden in an embedded char array in
  • Original method still getting called in Moq even after CallBase = true/false
  • Renaming class causes IBOutlet connection to fail
  • How to monitor transaction isolation level changes in SQL Profiler or in any other tool
  • How do i do the following curl command in Java
  • Passing and ArrayList through intent
  • Serializing socket
  • Symfony2 redirect to https route fails (uses wrong port)
  • ASP.NET RegularExpressionValidator, validate on a non-match?
  • Type safe keys with Entity Framework model
  • ASPNetCore MVC Routing Let Server Handle Specific Route
  • Replace Fragment with another on back button
  • Adding Parent and Child Nodes in TreeView from Sql Server 2008
  • How to upload specific List image using click on Upload button
  • Get localized short date pattern as String?
  • Blackberry 6: how to detect a long click on track pad?
  • unable to get jsonEncode in magento2
  • Building Qt project for C++11 standard
  • Authentication failed with Azure Active Directory in Windows Phone
  • How to get listview position?
  • In matplotlib, how do you change the fontsize of a single figure?
  • Spring: No transaction manager has been configured
  • npm 5.4.1 install/uninstall all failing
  • Autofac with Web API 2 - Parameter-less constructor error
  • Laravel: Getting Session ID oddly truncates when using foreach
  • accepts_nested_attributes_for practical form use for in Rails 3
  • Object and struct member access and address offset calculation
  • Bypass multiple inheritance in Java
  • OpenGL 3.3 on Mac OSX El Capitan with LWJGL
  • C++ Partial template specialization - design simplification
  • NHibernate Validation Localization with S#arp Architecture
  • How to rebase a series of branches?
  • Recording logins for password protected directories
  • How to access EntityManager inside Entity class in EJB3
  • how to do an event when i swipe from fragment to the other
  • Bug in WPF DataGrid
  • Running a C# exe file
  • Redux, normalised entities and lodash merge
  • how does django model after text[] in postgresql [duplicate]