WCF 故障合约因 NamedPipe 失败
我有一个使用 WCF 和命名管道的简单 IPC 机制。我的目标是将异常详细信息(包括堆栈跟踪)传播到客户端以进行日志记录(应用程序日志记录的其余部分位于客户端上)。
如果我使用以下代码,我可以捕获FaultException
Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract(typeof(Exception))]
void DoSomething();
}
Implement:
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!");
}
}
这工作正常,我看到控制台上打印的消息。但是,如果我想使用自己的派生异常而不是 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) { }
}
更改 IService.DoSomething 上的 FaultContract 以将
typeof(MyException).
Service 中的 throw 子句更改为将
new FaultException<MyException>(new MyException(e.Message, e);
客户端中的 catch 子句更改为
catch (FaultException<MyException> e)
当我执行此操作时,客户端上会捕获 CommunicationException,并显示以下错误: System.ServiceModel.CommunicationException:从管道读取时出错:管道已结束。 (109, 0x6d)。
MyException 类位于客户端和服务器均可使用的共享库中。
这个问题与
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:
System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
The MyException class is in a shared library available to both the client and server.
This question is very similar to this question, but that did not help me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过编写自己的错误 DataContract 解决了这个问题,其中包含 StackFrame 的序列化列表。
显然这篇 MSDN 文章不完全准确?
http://msdn.microsoft.com/en-us/library/ff649840.aspx
I resolved this by writing my own fault DataContract which contained a serialized list of StackFrames.
Apparently this MSDN article is not exactly accurate?
http://msdn.microsoft.com/en-us/library/ff649840.aspx