【问题标题】:Proper way to throw exception over WCF通过 WCF 引发异常的正确方法
【发布时间】:2015-06-30 12:25:33
【问题描述】:

我正在尝试以最通用的方式通过 WCF 发送异常。这是我得到的:

[ServiceContract]
interface IContract
{
    [OperationContract]
    void Foo();
}

class ContractImplementation: IContract
{
    public void Foo()
    {
        try
        {
            Bar();
        }
        catch (Exception ex)
        {
            throw new FaultException<Exception>(ex, ex.Message);
        }
    }
}

实际上来自Bar 的异常是:

[Serializable]
class MyException : Exception
{
    // serialization constructors
}

我在服务器端 WCF 日志记录中看到的错误是:

键入带有数据的“MyException” 合同名称 '我的异常:http://schemas.datacontract.org/2004/07/MyException' 预计不会。考虑使用 DataContractResolver 或添加任何 已知类型列表中静态未知的类型 - 例如, 通过使用 KnownTypeAttribute 属性或将它们添加到 传递给 DataContractSerializer 的已知类型列表。

到目前为止我已经尝试过:

[ServiceKnownType(typeof(MyException))]
[ServiceContract]
interface IContract
{
    [FaultContract(typeof(MyException))]
    [OperationContract]
    void Foo();
}

但没有运气。

【问题讨论】:

  • 可能是因为你抛出了新的 FaultException(ex, ex.Message);而不是“抛出新的 FaultException(ex, ex.Message);” ?另外,FaultException 的 TDetail 不一定是异常
  • @hazzik:我将实际异常放在详细信息中,因为我想在客户端重新抛出它。

标签: c# .net wcf


【解决方案1】:

首先,在 MyException 中,移除对 Exception 的继承并将其公开。

其次,当你声明你的服务合同时,声明异常如下:

[FaultContractAttribute(
        typeof(MyException),
        Action = "", 
        Name = "MyException", 
        Namespace = "YourNamespace")]
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults = true)]
    [OperationContract]
    void Foo()

最后,您可以像这样抛出异常:

throw new FaultException<MyException>
             (
                 new MyException(ex.Message),
                 new FaultReason("Description of your Fault")

             );

希望对你有帮助。

【讨论】:

  • 谢谢,这成功了。可悲的是,对于从我的异常超类继承的每种类型,我似乎都必须有明确的 throw 语句。
【解决方案2】:

首先 - 抱歉,我宁愿将此作为评论发布,而不是作为答案。作为一个相对的菜鸟,我做不到!

本文详细讨论了如何将异常详细信息转发回来:http://www.codeproject.com/Articles/799258/WCF-Exception-FaultException-FaultContract

Afaik,您实际上不能将异常本身传递回客户端,因为异常不符合 SOAP。还要考虑传递整个异常是否会损害代码的安全性。

【讨论】:

  • 如果您阅读了 OP 的帖子,他们已经尝试实现 FaultException。您链接到的文章是关于如何实现 FaultException。即使作为评论,这也无助于 OP。如果您对他们应该如何更改代码有任何建议,请发布。很抱歉我太苛刻了,我知道你想提供帮助,但这不是一个好的答案。
  • 另外你记错了。抛出一个 FaultException 并让它冒泡返回给调用者正是你应该应该这样做。然后调用者可以在他们的调用代码中自然地捕获和处理异常。
  • @Tom Redfern,我认为这有点苛刻。接受的答案会引发用户类型的错误异常。此类型不是从 Exception 继承的,因此不是 Exception 本身。这正是发布的文章所暗示的。另外,我没有建议用户不要通过 FaultException,纯粹是传递打包完整的异常细节可能不是一个好主意。
  • 道歉 - 也许这太苛刻了。我假设 您实际上不能将异常本身传递回客户端,您是在断言将 FaultException 传递回客户端是不正确的。我现在明白这不是你的目标。但是,我仍然认为您的回答没有帮助,因为您没有发布解决方案,而是链接到包含解决方案的文章而不引用相关位(有关链接时的操作,请参阅stackoverflow.com/help/how-to-answer)。如果您对您的答案进行编辑,我将删除反对票(在您这样做之前,投票锁定我)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多