C# 通过NamedPipe传递异常和子类
我试图通过NamedPipe传递Exception类型的对象(或者它的一个子类) 服务合同:C# 通过NamedPipe传递异常和子类,c#,.net,wcf,netnamedpipebinding,C#,.net,Wcf,Netnamedpipebinding,我试图通过NamedPipe传递Exception类型的对象(或者它的一个子类) 服务合同: [ServiceContract] public interface IWCFCallback { [OperationContract] void sendException(Exception e); } [ServiceContract] public interface IWCFCallback { [OperationContract] void sendEx
[ServiceContract]
public interface IWCFCallback
{
[OperationContract]
void sendException(Exception e);
}
[ServiceContract]
public interface IWCFCallback
{
[OperationContract]
void sendException(ExceptionInfo e);
}
当我这样使用它时,效果很好:
_pipeproxy.sendException(new Exception("bla bla 99"));
/// <summary>
/// Represents errors that occur during application execution.
/// </summary>
[DataContract]
public class ExceptionInfo
{
/// <summary>
/// Gets the type of the exception.
/// </summary>
[DataMember]
public string ExceptionType
{
get;
set;
}
/// <summary>
/// Gets a message that describes the current exception.
/// </summary>
/// <returns>
/// The error message that explains the reason for the exception, or an empty string("").
/// </returns>
[DataMember]
public string Message
{
get;
set;
}
/// <summary>
/// Gets the <see cref="T:System.Exception"/> instance that caused the current exception.
/// </summary>
/// <returns>
/// An instance of Exception that describes the error that caused the current exception. The InnerException property returns the same value as was passed into the constructor, or a null reference (Nothing in Visual Basic) if the inner exception value was not supplied to the constructor. This property is read-only.
/// </returns>
[DataMember]
public ExceptionInfo InnerException
{
get;
set;
}
/// <summary>
/// Gets a string representation of the immediate frames on the call stack.
/// </summary>
/// <returns>
/// A string that describes the immediate frames of the call stack.
/// </returns>
[DataMember]
public string StackTrace
{
get;
set;
}
/// <summary>
/// Gets or sets a link to the help file associated with this exception.
/// </summary>
/// <returns>
/// The Uniform Resource Name (URN) or Uniform Resource Locator (URL).
/// </returns>
[DataMember]
public string HelpLink
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the application or the object that causes the error.
/// </summary>
[DataMember]
public string Source
{
get;
set;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExceptionInfo"/> class.
/// </summary>
/// <param name="exception">The exception.</param>
/// <exception cref="ArgumentNullException">exception</exception>
public ExceptionInfo(Exception exception)
{
if(exception == null)
throw new ArgumentNullException("exception");
ExceptionType = exception.GetType().FullName;
HelpLink = exception.HelpLink;
Message = exception.Message;
Source = exception.Source;
StackTrace = exception.StackTrace;
if(exception.InnerException != null)
{
InnerException = new ExceptionInfo(exception.InnerException);
}
}
}
但一旦我通过一个子类:
_pipeproxy.sendException(new ArgumentException("fridgemaster 3000"));
我得到一个例外,说反序列化失败了
我已经读过KnownTypes属性,但是我不知道如何将它用于我自己没有实现的类
有人能给我一个提示吗?关于WCF的“最佳实践”之一是不要序列化异常。如果您的ServiceHost正在引发异常,则假定您使用FaultException。
异常传输不安全的原因之一是,异常本身是可序列化的,但您可以从中派生,谁能保证您的自定义派生异常是可序列化的
您可以将异常堆栈作为字符串和类型作为枚举传递数据协定对象,作为一种变通方法 这可能不符合最佳实践,但您可以创建一个表示异常的DataContract,如下所示:
_pipeproxy.sendException(new Exception("bla bla 99"));
/// <summary>
/// Represents errors that occur during application execution.
/// </summary>
[DataContract]
public class ExceptionInfo
{
/// <summary>
/// Gets the type of the exception.
/// </summary>
[DataMember]
public string ExceptionType
{
get;
set;
}
/// <summary>
/// Gets a message that describes the current exception.
/// </summary>
/// <returns>
/// The error message that explains the reason for the exception, or an empty string("").
/// </returns>
[DataMember]
public string Message
{
get;
set;
}
/// <summary>
/// Gets the <see cref="T:System.Exception"/> instance that caused the current exception.
/// </summary>
/// <returns>
/// An instance of Exception that describes the error that caused the current exception. The InnerException property returns the same value as was passed into the constructor, or a null reference (Nothing in Visual Basic) if the inner exception value was not supplied to the constructor. This property is read-only.
/// </returns>
[DataMember]
public ExceptionInfo InnerException
{
get;
set;
}
/// <summary>
/// Gets a string representation of the immediate frames on the call stack.
/// </summary>
/// <returns>
/// A string that describes the immediate frames of the call stack.
/// </returns>
[DataMember]
public string StackTrace
{
get;
set;
}
/// <summary>
/// Gets or sets a link to the help file associated with this exception.
/// </summary>
/// <returns>
/// The Uniform Resource Name (URN) or Uniform Resource Locator (URL).
/// </returns>
[DataMember]
public string HelpLink
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the application or the object that causes the error.
/// </summary>
[DataMember]
public string Source
{
get;
set;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExceptionInfo"/> class.
/// </summary>
/// <param name="exception">The exception.</param>
/// <exception cref="ArgumentNullException">exception</exception>
public ExceptionInfo(Exception exception)
{
if(exception == null)
throw new ArgumentNullException("exception");
ExceptionType = exception.GetType().FullName;
HelpLink = exception.HelpLink;
Message = exception.Message;
Source = exception.Source;
StackTrace = exception.StackTrace;
if(exception.InnerException != null)
{
InnerException = new ExceptionInfo(exception.InnerException);
}
}
}
用法:
try
{
// .....
}
catch (Exception ex)
{
var info = new ExceptionInfo(ex);
// do something....
}