Comment gérer WebFaultException pour renvoyer CustomException?

J’ai créé mon exception personnalisée qui sera lancée dans try-catch à chaque erreur

[Serializable] public class CustomException : Exception { public CustomException() { } public CustomException(ssortingng message) : base(message) { } public CustomException(ssortingng message, Exception innerException) : base(message, innerException) { } } 

J’ai deux services, REST et SOAP. Pour les services SOAP, je n’ai aucun problème à lancer mon exception personnalisée. Mais dans REST, j’ai rencontré beaucoup de difficultés.

Voici la méthode pour lancer une exception WebFaultException:

  public static WebFaultException RestGetFault(ServiceFaultTypes fault) { ServiceFault serviceFault = new ServiceFault(); serviceFault.Code = (int)fault; serviceFault.Description = ConfigAndResourceComponent.GetResourceSsortingng(fault.ToSsortingng()); FaultCode faultCode = new FaultCode(fault.ToSsortingng()); FaultReasonText faultReasonText = new FaultReasonText(serviceFault.Description); FaultReason faultReason = new FaultReason(faultReasonText); WebFaultException webfaultException = new WebFaultException(serviceFault, HttpStatusCode.InternalServerError); throw webfaultException; } 

ServiceFault est une classe dans laquelle il possède certaines propriétés que j’utilise pour mettre toutes les informations dont j’ai besoin.

J’utilise cette méthode pour lever une exception dans le service REST:

  public static CustomException GetFault(ServiceFaultTypes fault) { ssortingng message = fault.ToSsortingng(); CustomException cusExcp = new CustomException(message, new Exception(message)); throw cusExcp; } 

Un exemple de service REST (méthode de connexion):

  [WebInvoke(UriTemplate = "Login", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] public Session Login(ClientCredentials client, LogCredentials loginfo) { try { // Login process return copied; } catch (LogicClass.CustomException ex) { LogicClass.RestGetFault(LogicClass.EnumComponent.GetServiceFaultTypes(ex.Message)); throw ex; } } 

La partie MVC:

Manette:

  [HttpPost] public ActionResult Login(LoginCredentials loginfo) { try { ssortingng param = "{\"client\":" + JSonHelper.Serialize(new ClientAuthentication() { SessionID = Singleton.ClientSessionID }) + ", \"loginfo\":" + JSonHelper.Serialize(loginfo) + "}"; ssortingng jsonresult = ServiceCaller.Invoke(Utility.ConstructRestURL("Authenticate/Login"), param, "POST", "application/json"); UserSessionDTO response = JSonHelper.Deserialize(jsonresult); } catch (Exception ex) { return Json(new { status = ex.Message, url = ssortingng.Empty }); } return Json(new { status = "AUTHENTICATED", url = ssortingng.IsNullOrWhiteSpace(loginfo.r) ? Url.Action("Index", "Home") : loginfo.r }); } 

J’utilise ServiceCaller.Invoke pour appeler l’API REST et récupérer la réponse: ServiceCaller.cs

 public class ServiceCaller { public static ssortingng Invoke(ssortingng url, ssortingng parameters, ssortingng method, ssortingng contentType) { ssortingng results = ssortingng.Empty; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url)); request.Method = method; request.ContentType = contentType; if (!ssortingng.IsNullOrEmpty(parameters)) { byte[] byteArray = Encoding.UTF8.GetBytes(parameters); request.ContentLength = byteArray.Length; Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); } try { HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (HttpStatusCode.OK == response.StatusCode) { Stream responseStream = response.GetResponseStream(); int length = (int)response.ContentLength; const int bufSizeMax = 65536; const int bufSizeMin = 8192; int bufSize = bufSizeMin; if (length > bufSize) bufSize = length > bufSizeMax ? bufSizeMax : length; byte[] buf = new byte[bufSize]; SsortingngBuilder sb = new SsortingngBuilder(bufSize); while ((length = responseStream.Read(buf, 0, buf.Length)) != 0) sb.Append(Encoding.UTF8.GetSsortingng(buf, 0, length)); results = sb.ToSsortingng(); } else { results = "Failed Response : " + response.StatusCode; } } catch (Exception exception) { throw exception; } return results; } } 

Je m’attends à ce que le service REST renvoie cette information côté client:

entrez la description de l'image ici

Mais au final, il retourne toujours ceci:

entrez la description de l'image ici

Que devrais-je faire? S’il vous plaît aider.

MODIFIER

Voici l’exemple de réponse lorsque vous appelez le service de soap:

 [FaultException: InvalidLogin] System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +9441823 

Avez-vous vu le “InvalidLogin”? C’est ce que je veux voir dans la réponse du service REST.
Exemple de réponse de REST:

 [WebException: The remote server returned an error: (500) Internal Server Error.] System.Net.HttpWebRequest.GetResponse() +6115971 

Je lance une WebFaultException mais je reçois une WebException .
Si je ne parviens pas à récupérer le message d’erreur exact sur REST, je choisirai SOAP.
Merci pour les réponses.

Lorsque vous utilisez HttpWebRequest (ou un client Javascript), votre exception personnalisée n’a aucune signification pour eux. Juste les codes d’erreur HTTP (comme 500 Erreur de serveur interne ) et les données dans le contenu de la réponse.

Donc, vous devez gérer l’exception par vous-même. Par exemple, si vous attrapez WebException vous pouvez lire le contenu (le message d’erreur) au format XML ou Json en fonction de la configuration de votre serveur.

 catch (WebException ex) { var error = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd(); //Parse your error ssortingng & do something } 

Je viens d’avoir un problème similaire il y a quelques minutes. Peut-être que ça aide. J’essayais d’utiliser une extension pour tous mes appels de service, comme ci-dessous:

Voici le mauvais morceau de code:

 public static void ExecuteServiceMethod(this IMyRESTService svc, Action svcMethod) { try { // try to get first last error here ssortingng lastError = svc.CommHandler.CH_TryGetLastError(); if (!Ssortingng.IsNullOrEmpty(lastError)) throw new WebFaultException(lastError, System.Net.HttpStatusCode.InternalServerError); // execute service method svcMethod(); } catch (CommHandlerException ex) { // we use for now only 'InternalServerError' if (ex.InnerException != null) throw new WebFaultException(ex.InnerException.Message, System.Net.HttpStatusCode.InternalServerError); else throw new WebFaultException(ex.Message, System.Net.HttpStatusCode.InternalServerError); } catch (Exception ex) { throw new WebFaultException(ex.Message, System.Net.HttpStatusCode.InternalServerError); } } 

Voici le morceau de code FIXED :

 public static void ExecuteServiceMethod(this IMyRESTService svc, Action svcMethod) { // try to get first last error here ssortingng lastError = svc.CommHandler.CH_TryGetLastError(); if (!Ssortingng.IsNullOrEmpty(lastError)) throw new WebFaultException(lastError, System.Net.HttpStatusCode.InternalServerError); try { // execute service method svcMethod(); } catch (CommHandlerException ex) { // we use for now only 'InternalServerError' if (ex.InnerException != null) throw new WebFaultException(ex.InnerException.Message, System.Net.HttpStatusCode.InternalServerError); else throw new WebFaultException(ex.Message, System.Net.HttpStatusCode.InternalServerError); } catch (Exception ex) { throw new WebFaultException(ex.Message, System.Net.HttpStatusCode.InternalServerError); } } 

Donc … Vous avez probablement remarqué que le tout premier throw , est traité dans le bloc catch (Exception ex) qui le relance à nouveau, le faisant toujours afficher: “Erreur interne du serveur “. Peut-être que ça aide, car je vois que vous avez aussi une vision globale

catch (exception d’exception) {exception de projection; }

qui pourrait en être la cause.

1) Ajouter faultcontract à la méthode / à l’opération

2) Lance une exception WebFaultException ou WebFaultException

3) Côté client, saisissez webexception puis lisez la réponse à l’exception

 catch (WebException exception) { var resp = new StreamReader(exception.Response.GetResponseStream()).ReadToEnd(); } 

Même problème que celui mentionné dans la déclaration du problème et capable de résoudre avec la réponse mentionnée par LB et suivi de quelques autres postes. Donc, résumant les étapes suivies