54

我在 WCF 服务中有以下代码,可以根据某些情况引发自定义错误。我收到“此故障的创建者未指定原因”异常。我究竟做错了什么?

//source code
if(!DidItPass)
{
    InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
    throw new FaultException<InvalidRoutingCodeFault>(fault);
}

//operation contract
[OperationContract]
[FaultContract(typeof(InvalidRoutingCodeFault))]
bool MyMethod();

//data contract
[DataContract(Namespace="http://myuri.org/Simple")]
public class InvalidRoutingCodeFault
{
    private string m_ErrorMessage = string.Empty;

    public InvalidRoutingCodeFault(string message)
    {
        this.m_ErrorMessage = message;
    }

    [DataMember]
    public string ErrorMessage
    {
        get { return this.m_ErrorMessage; }
        set { this.m_ErrorMessage = value; }
    }
}
4

10 回答 10

49

经过一些额外的研究,以下修改后的代码有效:

if(!DidItPass)
{    
    InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");    
    throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason("Invalid Routing Code - No Approval Started"));
}
于 2008-12-04T19:07:09.673 回答
18

简短的回答是您没有做错任何事,只是错误地读取了结果。

在客户端,当您捕获错误时,捕获的内容是System.ServiceModel.FaultException<InvalidRoutingCodeFault>.
您的InvalidRoutingCodeFault对象实际上在.detailFaultException 的属性中。所以....

// 客户端代码

private static void InvokeMyMethod() 
{ 
    ServiceClient service = new MyService.ServiceClient(); 

    try 
    { 
        service.MyMethod(); 
    } 
    catch (System.ServiceModel.FaultException<InvalidRoutingCodeFault> ex) 
    { 
        // This will output the "Message" property of the System.ServiceModel.FaultException
        // 'The creator of this fault did not specify a Reason' if not specified when thrown
        Console.WriteLine("faultException Message: " + ex.Message);    
        // This will output the ErrorMessage property of your InvalidRoutingCodeFault type
        Console.WriteLine("InvalidRoutingCodeFault Message: " + ex.Detail.ErrorMessage);    
    } 
}

FaultException 的 Message 属性是错误页面上显示的内容,因此如果没有像 John Egerton 的帖子中那样填充它,您将看到“此错误的创建者未指定原因”消息。为了方便地填充它,在服务中抛出错误时使用两个参数构造函数,如下所示,从错误类型传递错误消息:

InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");                                          
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason(fault.ErrorMessage));                                      
于 2012-09-10T20:12:35.923 回答
9
serviceDebug includeExceptionDetailInFaults="true"

不是解决方案

以下代码甚至可以使用serviceDebug includeExceptionDetailInFaults="false"

// data contract 

[DataContract]
public class FormatFault
{
    private string additionalDetails;

    [DataMember]
    public string AdditionalDetails
    {
        get { return additionalDetails; }
        set { additionalDetails = value; }
    }
}

// interface method declaration

    [OperationContract]
    [FaultContract(typeof(FormatFault))]
    void DoWork2();

// service method implementation

    public void DoWork2()
    {
        try
        {
            int i = int.Parse("Abcd");
        }
        catch (FormatException ex)
        {
            FormatFault fault = new FormatFault();
            fault.AdditionalDetails = ex.Message;
            throw new FaultException<FormatFault>(fault);
        }
    }

// client calling code

    private static void InvokeWCF2()
    {
        ServiceClient service = new ServiceClient();

        try
        {
            service.DoWork2();
        }
        catch (FaultException<FormatFault> e)
        {
            // This is a strongly typed try catch instead of the weakly typed where we need to do -- if (e.Code.Name == "Format_Error")
            Console.WriteLine("Handling format exception: " + e.Detail.AdditionalDetails);   
        }
    }

如果不需要,则无需添加故障原因。只要确保 FaultContract 属性正确

于 2009-01-28T11:33:46.990 回答
5

我使用两个参数构造函数解决了这个问题。

// service method implementation

 throw new FaultException<FormatFault>(fault,new FaultReason(fault.CustomFaultMassage)); 

CustomFaultMassage 是数据合同的属性。

于 2010-07-08T09:17:47.723 回答
2

如果没有为方法指定 FaultContract(typeof(className)) 属性,也可能会遇到此异常

于 2009-01-28T11:21:37.373 回答
2

如果您不想收到此类异常的通知,请转到 Debug -> Exceptions 并取消选中“Common Language Runtime Exceptions”或特定异常的“User-unhandled”。

于 2010-04-14T09:39:11.820 回答
1

我的代码与 Rashmi 的代码一模一样,并且出现“此故障的创建者......”错误。当我在 VS2010 中调试时发生了这种情况。我找到了这篇文章:

http://sergecalderara.wordpress.com/2008/11/25/systemservicemodelfaultexception1-was-unhandled-by-user-code/

这解释了我需要关闭的几个调试选项。问题解决了。

于 2009-11-18T00:56:41.877 回答
0

您可以在服务器配置中尝试此操作(行为 -> 服务行为 -> 行为):

<serviceDebug includeExceptionDetailInFaults="true" />
于 2008-12-04T18:12:34.667 回答
0

通过使用强类型的 try catch,我能够解决错误“此错误的创建者没有指定原因”。

于 2009-04-15T00:43:55.977 回答
0

在客户端更新服务引用解决了这个问题。同样可以为你工作。

于 2010-09-21T22:50:45.627 回答