web-dev-qa-db-fra.com

"Le créateur de cette faute n'a pas spécifié de motif" Exception

J'ai le code suivant dans le service WCF pour lancer une erreur personnalisée en fonction de certaines situations. Je reçois une exception "Le créateur de cette erreur n'a pas spécifié de raison". Qu'est-ce que je fais mal?

//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; }
    }
}
52
Michael Kniskern

Après quelques recherches supplémentaires, le code modifié suivant a fonctionné:

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

La réponse courte est que vous ne faites rien de mal, juste en lisant les résultats de manière incorrecte.

Côté client, lorsque vous interceptez l'erreur, ce qui est intercepté est du type System.ServiceModel.FaultException<InvalidRoutingCodeFault>.
Votre objet InvalidRoutingCodeFault se trouve en fait dans le .detail propriété de FaultException. DONC....

// code client

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

La propriété Message de FaultException est ce qui est affiché sur la page d'erreur, donc si elle n'est pas renseignée comme dans le message de John Egerton, vous verrez le message `` Le créateur de cette erreur n'a pas spécifié de raison ''. Pour le remplir facilement, utilisez le constructeur à deux paramètres lors du lancement de l'erreur dans le service comme suit, en transmettant votre message d'erreur à partir de votre type d'erreur:

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

n'est PAS la solution

Le code suivant fonctionne même avec 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);   
        }
    }

Il n'est pas nécessaire d'ajouter la raison du défaut si ce n'est pas nécessaire. Assurez-vous simplement que l'attribut FaultContract est correct

8
Rashmi Pandit

J'ai résolu ce problème en utilisant un constructeur à deux paramètres.

// service method implementation

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

CustomFaultMassage est la propriété du contrat de données.

5
user386451

Si vous ne souhaitez pas être averti de ces exceptions, accédez à Debug -> Exceptions et décochez "User-unhandled" pour "Common Language Runtime Exceptions" ou pour des exceptions spécifiques.

2
sandeep patil

On peut également rencontrer cette exception si l'on ne spécifie pas l'attribut FaultContract (typeof (className)) pour la méthode

2
Rashmi Pandit

J'ai le code exactement comme Rashmi et j'ai l'erreur "Le créateur de cette faute ....". Cela se passait lorsque je déboguais dans VS2010. J'ai trouvé ce post:

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

ce qui expliquait quelques options de débogage que je devais désactiver. Problème résolu.

1
ScottG

Vous pouvez essayer ceci dans la configuration du serveur (comportements -> ServiceBehaviors -> comportement):

<serviceDebug includeExceptionDetailInFaults="true" />
0
Chris Porter

En utilisant try catch fortement tapé, j'ai pu contourner l'erreur "Le créateur de cette erreur n'a pas spécifié de raison".

0
UJ

La mise à jour de la référence de service dans le client a résolu le problème. La même chose pourrait fonctionner pour vous.

0
pencilslate