WCF FaultContract Error with NamedPipe

I have a simple IPC mechanism that uses WCF and named pipes. My goal is to distribute information about the details of the exception (including the stack) to the client for logging purposes (the rest of the application registration is on the client).

If I use the following code, I can catch a FaultException <Exception> on the client and view the 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 great and I see a message printed on the console. However, if I want to use my own derived exception instead of the Exception base 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 FaultContract to IService.DoSomething to

 typeof(MyException). 

Change the throw clause in the service to

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

Change the catch clause on the client to

 catch (FaultException<MyException> e) 

When I do this, the CommunicationException error appears on the client: System.ServiceModel.CommunicationException: An error occurred while reading from the pipe: the pipe was finished. (109, 0x6d).

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

This question is very similar to this question , but it did not help me.

+1
stack-trace named-pipes wcf faultexception
source share
1 answer

I solved this by writing my own DataContract error, which contained a serialized list of StackFrames.

Apparently this MSDN article is not entirely accurate?

http://msdn.microsoft.com/en-us/library/ff649840.aspx

 [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; } } 
+1
source share

All Articles