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; }
}
}
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"));
}
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));
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
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.
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.
On peut également rencontrer cette exception si l'on ne spécifie pas l'attribut FaultContract (typeof (className)) pour la méthode
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:
ce qui expliquait quelques options de débogage que je devais désactiver. Problème résolu.
Vous pouvez essayer ceci dans la configuration du serveur (comportements -> ServiceBehaviors -> comportement):
<serviceDebug includeExceptionDetailInFaults="true" />
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".
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.