【问题标题】:"The creator of this fault did not specify a Reason" Exception“此故障的创建者未指定原因”异常
【发布时间】:2010-09-25 09:15:19
【问题描述】:

我在 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; }
    }
}

【问题讨论】:

  • 你知道,这个信息在计算机编程之外还有一些非常深刻的哲学含义。
  • 我想我会在一段时间内将其添加为我的签名......谢谢迈克尔
  • 现在查看这个问题中的原始代码示例....(facepalm)

标签: c# .net wcf faults


【解决方案1】:

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

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"));
}

【讨论】:

【解决方案2】:

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

在客户端捕获错误时,捕获的是System.ServiceModel.FaultException&lt;InvalidRoutingCodeFault&gt; 类型。
您的InvalidRoutingCodeFault 对象实际上位于FaultException 的.detail 属性中。所以....

// 客户端代码

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));                                      

【讨论】:

    【解决方案3】:
    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 属性正确

    【讨论】:

    • e.Detail 部分是关键。这是 OP 问题的答案。
    【解决方案4】:

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

    // service method implementation
    
     throw new FaultException<FormatFault>(fault,new FaultReason(fault.CustomFaultMassage)); 
    

    CustomFaultMassage 是数据合约的属性。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        如果您不想收到此类异常的通知,请转到调试 -> 异常并取消选中“通用语言运行时异常”或特定异常的“用户未处理”。

        【讨论】:

          【解决方案7】:

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

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

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

          【讨论】:

            【解决方案8】:

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

            <serviceDebug includeExceptionDetailInFaults="true" />
            

            【讨论】:

            • 我在我的配置文件中设置为 true。
            • 好的,我认为这可能是一个比这更复杂的问题,但我总是想检查基础知识。很高兴您找到了解决方案!
            • 请注意,在 msdn 上,他们建议仅在调试时使用此设置,而不是在生产环境中使用。
            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-11-02
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多