首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用已知类型通过WCF传递复杂类型

使用已知类型通过WCF传递复杂类型
EN

Stack Overflow用户
提问于 2012-06-22 08:06:05
回答 3查看 3.7K关注 0票数 3

我在做WCF服务。

其中一个OperationContracts请求一个复杂类型作为参数之一(System.Exception是特定的)。

当客户端调用代理时,如果我创建了一个新的异常,例如。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 System.Exception toNewException = new Exception();

然后把它..。它运行得相当好。

但是如果我试图发送'System.Web.HttpUnhandledException‘类型的异常。类型未知的服务故障。(见下面的错误)

序列化参数http://tempuri.org/:Exception时出错。InnerException消息是“Type‘System.Web.HttpUnhandledException”,它的数据契约名为“HttpUnhandledException:http://schemas.datacontract.org/2004/07/System.Web”。将任何类型静态地添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。有关更多细节,请参见InnerException。

我研究过已知类型的属性..。但到目前为止,我还没有找到任何有帮助的例子或文档。

有人知道一个很好的信息来源,我可以如何改变我的客户机/服务器来接受/处理任何类型的异常?

让我的问题更详细一点..。错误状态;“将所有不静态已知的类型添加到已知类型的elist中”。这就是我想知道如何专门针对像system.exception这样的复杂的system.exception对象所做的事情。

更新

我试着做了以下修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[OperationContract]
[ServiceKnownType(typeof(HttpUnhandledException))]
void LogError(Exception Exception, Boolean LogInternalFlag, int UserId, int ApplicationId, int SeverityId);

最后我又犯了一个错误!

序列化参数http://tempuri.org/:Exception时出错。数据契约名为'ArrayOfKeyValueOfanyTypeanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays‘的InnerException消息是'Type 'System.Collections.ListDictionaryInternal’,这是不需要的。将任何类型静态地添加到已知类型列表中-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。有关更多细节,请参见InnerException。

至少例外的错误是有意义的..。我一点也不确定这意味着什么。

我还将尝试将异常序列化为xml并将其作为字符串传递.不幸的是,这并不像听起来那么简单,在序列化异常和任何内部异常时需要考虑许多因素。

EN

回答 3

Stack Overflow用户

发布于 2012-06-22 10:37:35

你的问题不是这种类型很复杂。您的问题是您的合同是用一个基类(异常)声明的,并且传入了一个子类(HttpUnhandledException)。您没有向契约序列化程序提供任何类型信息,说明子元素添加到基本定义中的内容。您可以通过KnownTypes提供额外的信息。

我在MSDN上在KnowTypes上看到的最好的文档是这里

搜索中缺少的是,由于您只有一个OperationContract (没有DataContract),所以您真正想要使用的属性是ServiceKnownType

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[ServiceContract]
public interface IContract
{
   [OperationContract]
   [ServiceKnownType(typeof(HttpUnhandledException))]
   void PassException(Exception c);
}

您可以将属性仅放在方法或整个接口上。

注意,如果您在编译时不知道所有可能的子(异常)类型,则使用运行时方法的ServiceKnownType (和KnowTypes)版本。

票数 2
EN

Stack Overflow用户

发布于 2012-06-22 12:02:02

ErnieL有正确的技术答案。然而,从务实的角度来看,我倾向于打破异常的各个部分,只传递这些部分,或者2)创建您自己的自定义ErrorLog类型并发送它。

这消除了处理异常对象子类的需要,并为您提供了一个可以使用的一致接口。很可能,您只需要一些来自异常的成员(错误消息、内部异常错误消息和堆栈跟踪)。

对于内部异常,只需编写一个循环遍历消息并将它们连接在一起的方法。它们真的需要分开存放吗?

票数 1
EN

Stack Overflow用户

发布于 2013-04-05 11:54:01

您可以通过将异常序列化为字节数组,然后反序列化服务器端来解决此问题。

客户端,您可以使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    try { /* Do something that generates an exception here. */ }
    catch(System.Exception exception)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, exception);
            YourWCFMethodHere(ms.ToArray());
        }
     }

然后在服务器端:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public void YourWCFMethodHere(byte[] exception)
    {
        using (MemoryStream ms = new MemoryStream(exception, false))
        {
            BinaryFormatter bf = new BinaryFormatter();
            Exception ex = (Exception)bf.Deserialize(ms);
            // Do something with the exception here
        }
    }

当然,您需要进行一些错误检查,以防传入的byte[]实际上不是一个异常。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11159985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文