3

我只是注意到了一些特别的东西。我有一个通过 basicHttpBinding 发布的内部库存服务,以及一个启用了元数据的 customBinding (http+binary)。我还包括了一个用于 http 的 mex 端点。我们使用 Visual Studio 2008 和 VB.NET

就在最近,我们注意到我们无法在其他项目中成功添加对此服务的服务引用。它所生成的只是我们通过 FaultContract 包含的第一个自定义异常(实际上,只有一种类型)。如果我添加一个简单的网络参考,它也可以正常工作。此外,WcfClient.exe 在加载服务时也没有问题。只是 VS.NET 添加服务引用是行不通的。

在服务中,此异常继承自 Exception 并标记为可序列化。这就是你应该做的,不是吗?

无论如何,这让我感到困惑。如果我删除此自定义异常的 FaultContract 一切正常。我可以添加服务参考,没问题。但是有没有办法我仍然可以拥有我的自定义异常?这是一个已知问题吗?

4

4 回答 4

8

我今天自己遇到了这个。解决方案是使用不继承自 FaultContract 中的 Exception 的对象。如果您查看有关FaultExceptionFaultContract的 MSDN 文档,您将看到官方示例使用普通类(具有 DataContact 属性)而不是扩展 FaultException.Detail 异常的类。我不确定为什么异常会导致添加服务引用失败,但我怀疑它与序列化或检索自定义异常的类型信息有关。我已经在示例实现之前和之后包含了以演示工作方法。

之前(没有工作):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyException))]
    MyResults MyServiceOperation(string myParameter);
}

[Serializable]
public class MyException : Exception
{
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

之后(工作):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    MyResults MyServiceOperation(string myParameter);
}

[DataContract]
public class MyFault
{
    [DataMember]
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

资料来源:Max Strini,感谢他使用他的代码并帮助找到解决此问题的方法。

于 2011-02-08T01:51:04.307 回答
1

我发现了以下关于如何使用继承自 System.Exception 的对象创建故障合同的文章:http: //blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

但是,它对我不起作用。我怀疑它对我不起作用的原因是我使用的是 BasicHttp 绑定而不是 .NET-.NET 绑定。

于 2012-07-31T20:06:41.217 回答
0

我也遇到过这个问题。我最终使用 svcutil.exe 来生成似乎没有遇到同样问题的代理。

于 2011-09-02T13:06:53.850 回答
0

我遇到了同样的问题,并通过使用 SVCUTIL.exe 生成代理来解决它。我完全按照 MSDN 推荐的方式进行了自定义故障设置,但“添加服务参考”不包括代理中的故障合同。然后我使用了 SVCUTIL,它就像魔术一样工作:)

于 2011-11-25T17:18:17.157 回答