Pergunta

Eu tenho o seguinte código no serviço WCF para lançar uma falha personalizada com base em determinadas situações. Estou recebendo uma exceção "o criador dessa falha não especificou um motivo". O que estou fazendo errado?

//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; }
    }
}
Foi útil?

Solução

Após algumas pesquisas adicionais, o código modificado a seguir funcionou:

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

Outras dicas

A resposta curta é que você não está fazendo nada errado, apenas lendo os resultados incorretamente.

No lado do cliente, quando você pega o erro, o que é capturado é do tipo System.ServiceModel.FaultException<InvalidRoutingCodeFault>.
Sua InvalidRoutingCodeFault objeto está realmente no .detail propriedade da falha. ASSIM....

// Código do cliente

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

A propriedade Mensagem da FagressException é o que é exibido na página de erro; portanto, se não for preenchida como na postagem de John Egerton, você verá o criador dessa falha não especificou um motivo '. Para preenchê -lo facilmente, use o construtor de dois parâmetros ao jogar a falha no serviço da seguinte maneira, passando sua mensagem de erro do seu tipo de falha:

InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");                                          
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason(fault.ErrorMessage));                                      
serviceDebug includeExceptionDetailInFaults="true"

não é a solução

O código a seguir funciona mesmo com 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);   
        }
    }

Não há necessidade de adicionar o motivo da falha se não for necessário. Apenas verifique se o atributo do contrato de falha está correto

Eu resolvi esse problema usando um construtor de dois parâmetros.

// service method implementation

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

CustomFaultMassage é propriedade do contrato de dados.

Também se pode encontrar esta exceção se não se especificar o atributo contrato de falha (tipoof (className)) para o método

Se você não deseja ser notificado de tais exceções, vá para a depuração -> exceções e desmarque "use -usedled" para "exceções de tempo de execução do idioma comum" ou para exceções específicas.

Eu tenho código exatamente como o erro Rashmi e recebi o erro "o criador dessa falha ....". Isso estava acontecendo quando eu estava depurando no VS2010. Eu encontrei este post:

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

O que explicou algumas opções de depuração que eu precisava desligar. Problema resolvido.

Você pode tentar isso na configuração do servidor (comportamentos -> ServiceBehaviors -> Comportamento):

<serviceDebug includeExceptionDetailInFaults="true" />

Ao usar o Try Catch fortemente digitado, consegui contornar o erro "O criador dessa falha não especificou um motivo".

A atualização da referência de serviço no cliente resolveu o problema. O mesmo poderia funcionar para você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top