.net 序列化WCF服务中的MethodBase和异常类型

.net 序列化WCF服务中的MethodBase和异常类型,.net,wcf,service,datacontractserializer,.net,Wcf,Service,Datacontractserializer,我为记录异常创建了一个WCF服务(我意识到,如果网络关闭,事情将不会被记录……有后备措施) 无论如何,它有两种方法 int LogException(MethodBase methodBase, Exception exception) int LogMessage(MethodBase methodBase, string message, string data) 当我尝试将服务添加到一个新项目中时,不会创建.cs文件。我运行了svcutil,将.cs和config设置复制到项目中,并尝试

我为记录异常创建了一个WCF服务(我意识到,如果网络关闭,事情将不会被记录……有后备措施)

无论如何,它有两种方法

int LogException(MethodBase methodBase, Exception exception)
int LogMessage(MethodBase methodBase, string message, string data)
当我尝试将服务添加到一个新项目中时,不会创建.cs文件。我运行了svcutil,将.cs和config设置复制到项目中,并尝试使用生成的客户端调用该服务。我得到了以下两个错误

尝试删除时出错 序列化参数 . 这个 InnerException消息为“类型” 'System.Reflection.RuntimeMethodInfo' 使用数据合同名称 'RuntimeMethodInfo:http://schemas.datacontract.org/2004/07/System.Reflection' 这是预料不到的。考虑使用 DataContractResolver或添加任何类型 列表中静态未知的 已知类型-例如,通过使用 KnownTypeAttribute属性或由 将它们添加到已知类型列表中 已传递给DataContractSerializer。“。 请参阅InnerException了解更多信息 细节

内部例外

类型 'System.Reflection.RuntimeMethodInfo' 使用数据合同名称 'RuntimeMethodInfo:http://schemas.datacontract.org/2004/07/System.Reflection' 这是预料不到的。考虑使用 DataContractResolver或添加任何类型 列表中静态未知的 已知类型-例如,通过使用 KnownTypeAttribute属性或由 将它们添加到已知类型列表中 传递给DataContractSerializer


我需要做些什么才能使这项工作正常进行?

当通过WCF进行通信时,WCF需要准确地知道将通过边界发送什么。因此,接受“异常”很好,但几乎总是要传递异常的子类型,因此需要告诉合同哪些类型的异常将跨越边界传递。MethodBase也是如此。您可能想告诉它,您实际上会在某些时候传递MethodInfo

因为这些不是您的类型,所以您可能无法使用KnownType属性(该属性通常放置在基类或接口上)。在这种情况下,您需要使用数据协定解析器。它告诉序列化/反序列化引擎如何查找子类型

尽管您可以使用ServiceKnownType属性。您的合同应如下所示:

[DataContract]
public interface ILoggingStuff // choose a better name than this
{
    [OperationContract]
    [ServiceKnownType(typeof(MethodInfo))]
    int LogException(MethodBase methodBase, Exception exception);
    [OperationContract]
    [ServiceKnownType(typeof(MethodInfo))]
    int LogMessage(MethodBase methodBase, string message, string data);
}

这告诉WCF MethodBase可能使用降序类型MethodInfo。

通过WCF进行通信时,WCF需要准确地知道将通过边界发送什么。因此,接受“异常”很好,但几乎总是要传递异常的子类型,因此需要告诉合同哪些类型的异常将跨越边界传递。MethodBase也是如此。您可能想告诉它,您实际上会在某些时候传递MethodInfo

因为这些不是您的类型,所以您可能无法使用KnownType属性(该属性通常放置在基类或接口上)。在这种情况下,您需要使用数据协定解析器。它告诉序列化/反序列化引擎如何查找子类型

尽管您可以使用ServiceKnownType属性。您的合同应如下所示:

[DataContract]
public interface ILoggingStuff // choose a better name than this
{
    [OperationContract]
    [ServiceKnownType(typeof(MethodInfo))]
    int LogException(MethodBase methodBase, Exception exception);
    [OperationContract]
    [ServiceKnownType(typeof(MethodInfo))]
    int LogMessage(MethodBase methodBase, string message, string data);
}

这告诉WCF MethodBase可能正在使用递减类型MethodInfo。

@McKay,我应该把它放在哪里?抱歉,轻微的内存丢失,您不能使用KnownType,因为它们不是您的类型(我想的是故障契约,它放在数据契约上),我还发现了这一点,其中提到它适用于异常,但是我不知道把dataContractSerializer/dataTypes配置信息放在哪里。。。在svc或消费应用程序中?@Chad:你正在一点一点地学习,为什么不传递你无法控制的数据,尤其是平台特定类型的数据。一旦.NET开始使用所传递类型之一的不同子类型,代码就会中断。总的来说,这是行不通的。你需要决定MethodBase的哪些部分,以及你感兴趣的异常的哪些部分,然后通过它们来代替。是的,这就是我最终要做的。似乎是一个黑客虽然,因为我已经有了一个对象与我想要的一切。。。啊,好吧。@McKay,我把这个放在哪里?抱歉,内存有点小问题,你不能使用KnownType,因为它们不是你的类型(我想的是错误契约,它放在数据契约上),我还发现这个提到它可以处理异常,但我不知道把dataContractSerializer/dataTypes配置信息放在哪里。。。在svc或消费应用程序中?@Chad:你正在一点一点地学习,为什么不传递你无法控制的数据,尤其是平台特定类型的数据。一旦.NET开始使用所传递类型之一的不同子类型,代码就会中断。总的来说,这是行不通的。你需要决定MethodBase的哪些部分,以及你感兴趣的异常的哪些部分,然后通过它们来代替。是的,这就是我最终要做的。似乎是一个黑客虽然,因为我已经有了一个对象与我想要的一切。。。好吧。