Les données JSON renvoyées par le service WCF contiennent des caractères d’échappement

J’ai une application WCF – WPF qui fonctionne, mais je recherche une optimisation. Ci-dessous se trouve mon code où un service reposant WCF expose un tableau JSON et qu’une interface utilisateur WPF reçoit sans problème.

WCF:

public clsStatus[] GetAllStatus() { DataTable dt = new DataTable(); List lstGetAllStatus = new List(); try { dt = // My Data Table foreach (DataRow dr in dt.Rows) { dcStatus objGetAllStatus = new clsStatus(); objGetAllStatus.Id = Convert.ToInt32(dr["Id"]); objGetAllStatus.Status = dr["Status"].ToSsortingng(); lstGetAllStatus.Add(objGetAllStatus); } } return lstGetAllStatus.ToArray(); } 

Dans l’interface WPF:

 public ObservableCollection InvokeGet(ssortingng sUrl) { System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl); request.Method = "GET"; request.UseDefaultCredentials = true; request.ContentLength = 0; System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse; Stream objResponseStream = response.GetResponseStream(); StreamReader reader = new StreamReader(objResponseStream); ssortingng objResponseSsortingng = reader.ReadToEnd(); response.Close(); JavaScriptSerializer objJsonserialiser = new JavaScriptSerializer(); objJsonserialiser.MaxJsonLength = 999999999; T[] arrResult = objJsonserialiser.Deserialize(objResponseSsortingng); return new ObservableCollection(arrResult); } 

De cette façon, la sérialisation / désérialisation fonctionne bien, alors que lorsque je fais les modifications indiquées ci-dessous, la désérialisation ne fonctionne plus:

En WCF:

 public ssortingng[] GetAllStatus() { DataTable dt = new DataTable(); try { dt = // My Data Table ssortingng jsonresp = JsonConvert.SerializeObject(dt, Formatting.None); } return jsonresp; } 

En WPF:

 public ObservableCollection InvokeGet(ssortingng sUrl ) { System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl); request.Method = "GET"; request.UseDefaultCredentials = true; request.ContentLength = 0; System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse; Stream objResponseStream = response.GetResponseStream(); StreamReader reader = new StreamReader(objResponseStream); ssortingng objResponseSsortingng = reader.ReadToEnd(); response.Close(); dsReportRequests dsrepreq = new dsReportRequests(); //This conversion is failing with error dsrepreq = JsonConvert.DeserializeObject(objResponseSsortingng); } 

Erreur: "Error converting value \"[{\"Id\":11280,\"statName}]\" to type 'clsStat[]'. Path '', line 1, position 759." "Error converting value \"[{\"Id\":11280,\"statName}]\" to type 'clsStat[]'. Path '', line 1, position 759."

J’ai découvert que le format JSON dans le code modifié contient des caractères d’échappement ( \ ), ce qui semble provoquer l’erreur lors de la désérialisation.

Votre JSON se double-sérialisé. (Les barres obliques inverses supplémentaires dans le JSON en sont symptomatiques.)

Notez que dans la première version, vous ne faites pas appel à la sérialisation de l’object de retour dans GetAllStatus() , mais dans InvokeGet() vous effectuez un appel pour la désérialiser. Et ça marche. Donc, d’une manière ou d’une autre, l’object de retour de GetAllStatus doit être sérialisé automatiquement. Il doit être clair que WCF doit gérer la sérialisation de votre object de retour pour vous.

Dans la deuxième version, vous sérialisez manuellement l’object de retour dans GetAllStatus() aide de JsonConvert.SerializeObject() . Comme nous venons d’établir que WCF effectue également la sérialisation, vous vous retrouvez avec un JSON à double sérialisation.

Pour que cela fonctionne, vous devez vous assurer que la sortie n’est sérialisée qu’une seule fois. Je suppose que vous aviez une raison de commencer à utiliser Json.Net dans votre service. Je chercherais donc un moyen de remplacer le sérialiseur WCF par JSON.Net. Vous n’avez pas à chercher loin – il y a pas mal de questions et de réponses sur StackOverflow qui traitent de ce sujet même. Voici quelques idées:

  • remplacez JavascriptSerializer intégré par WCF par le sérialiseur json.Net json.Net de Newtonsoft (Synopsis: écrivez un formateur de messages personnalisé et configurez WCF pour l’utiliser)
  • Remplacer le sérialiseur JSON par défaut dans WCF 4 par JSON.NET (Synopsis: sérialiser manuellement sur un stream et contourner complètement la sérialisation WCF)
  • Service Web RESTful WCF avec JSON.Net: évitez la sérialisation double (Synopsis: utilisez l’API Web au lieu de WCF car il utilise déjà Json.Net par défaut)