使用包含System.Exception的自定义FaultContract对象会导致“添加服务引用”失败

时间:2011-01-11 09:49:17

标签: wcf visual-studio-2008 metadata faultcontract

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

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

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

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

4 个答案:

答案 0 :(得分:8)

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

之前(没有工作):

[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使用他的代码并帮助找到解决此问题的方法。

答案 1 :(得分:1)

我发现以下文章介绍了如何使用从System.Exception继承的对象创建错误契约:http://blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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