MVC: comment renvoyer une chaîne en tant que JSON

Afin de rendre un processus de rapport de progression un peu plus fiable et de le découpler de la demande / réponse, j’effectue le traitement dans un service Windows et je persiste à répondre à un fichier. Lorsque le client commence à interroger les mises à jour, le but est que le contrôleur renvoie le contenu du fichier, quel qu’il soit, sous la forme d’une chaîne JSON.

Le contenu du fichier est pré-sérialisé en JSON. Cela permet de s’assurer qu’il n’ya rien qui entrave la réponse. Aucun traitement ne doit être effectué (à moins de lire le contenu du fichier dans une chaîne et de le renvoyer) pour obtenir la réponse.

Je pensais au départ que cela serait assez simple, mais cela ne s’avère pas être le cas.

Actuellement, ma méthode de contrôleur ressemble à ceci:

Manette

Actualisé

[HttpPost] public JsonResult UpdateBatchSearchMembers() { ssortingng path = Properties.Settings.Default.ResponsePath; ssortingng returntext; if (!System.IO.File.Exists(path)) returntext = Properties.Settings.Default.EmptyBatchSearchUpdate; else returntext = System.IO.File.ReadAllText(path); return this.Json(returntext); } 

Et Fiddler retourne ceci comme réponse brute

 HTTP/1.1 200 OK Server: ASP.NET Development Server/10.0.0.0 Date: Mon, 19 Mar 2012 20:30:05 GMT X-AspNet-Version: 4.0.30319 X-AspNetMvc-Version: 3.0 Cache-Control: private Content-Type: application/json; charset=utf-8 Content-Length: 81 Connection: Close "{\"StopPolling\":false,\"BatchSearchProgressReports\":[],\"MemberStatuses\":[]}" 

AJAX

Actualisé

Ce qui suit sera probablement modifié plus tard, mais pour l’instant, cela fonctionnait lorsque je générais la classe de réponse et la renvoyais en tant que JSON comme une personne normale.

 this.CheckForUpdate = function () { var parent = this; if (this.BatchSearchId != null && WorkflowState.SelectedSearchList != "") { showAjaxLoader = false; if (progressPending != true) { progressPending = true; $.ajax({ url: WorkflowState.UpdateBatchLink + "?SearchListID=" + WorkflowState.SelectedSearchList, type: 'POST', contentType: 'application/json; charset=utf-8', cache: false, success: function (data) { for (var i = 0; i < data.MemberStatuses.length; i++) { var response = data.MemberStatuses[i]; parent.UpdateCellStatus(response); } if (data.StopPolling = true) { parent.StopPullingForUpdates(); } showAjaxLoader = true; } }); progressPending = false; } } 

Le problème, je pense, est que le résultat de l’action Json est destiné à prendre un object (votre modèle) et à créer une réponse HTTP avec du contenu en tant que données au format JSON provenant de votre object modèle.

Ce que vous transmettez à la méthode Json du contrôleur, cependant, est un object de chaîne au format JSON, il est donc en train de “sérialiser” l’object de chaîne en JSON, ce qui explique pourquoi le contenu de la réponse HTTP est entouré de guillemets (I ‘ m en supposant que c’est le problème).

Je pense que vous pouvez envisager d’utiliser le résultat de l’action Content comme alternative au résultat de l’action Json, car vous disposez déjà du contenu brut pour la réponse HTTP disponible.

 return this.Content(returntext, "application/json"); // not sure off-hand if you should also specify "charset=utf-8" here, // or if that is done automatically 

Une autre solution consisterait à désérialiser le résultat JSON du service dans un object, puis à transmettre cet object à la méthode Json du contrôleur, mais l’inconvénient est que vous désérialisez puis re-sérialisez les données, ce qui peut être inutile. pour vos fins.

Il vous suffit de renvoyer ContentResult standard et de définir ContentType sur “application / json”. Vous pouvez créer un ActionResult personnalisé pour cela:

 public class JsonSsortingngResult : ContentResult { public JsonSsortingngResult(ssortingng json) { Content = json; ContentType = "application/json"; } } 

Et puis retourne son instance:

 [HttpPost] public JsonResult UpdateBatchSearchMembers() { ssortingng returntext; if (!System.IO.File.Exists(path)) returntext = Properties.Settings.Default.EmptyBatchSearchUpdate; else returntext = Properties.Settings.Default.ResponsePath; return new JsonSsortingngResult(returntext); } 

Ouais c’est tout sans autres problèmes, pour éviter json de chaîne brute c’est ça.

  public ActionResult GetJson() { var json = System.IO.File.ReadAllText( Server.MapPath(@"~/App_Data/content.json")); return new ContentResult { Content = json, ContentType = "application/json", ContentEncoding = Encoding.UTF8 }; } 

REMARQUE: notez que le type de retour de méthode de JsonResult ne fonctionne pas pour moi, car JsonResult et ContentResult héritent tous deux d’ ActionResult mais ils ne sont pas liés.

Toutes les réponses ici fournissent un bon code de travail. Mais quelqu’un ne serait pas satisfait du fait qu’ils utilisent tous ContentType comme type de retour et non JsonResult .

Malheureusement, JsonResult utilise JavaScriptSerializer sans option pour le désactiver. La meilleure façon de contourner ce JsonResult est d’hériter de JsonResult .

J’ai copié la plupart du code à partir de JsonResult origine et créé la classe JsonSsortingngResult qui renvoie la chaîne transmise sous forme d’ application/json . Code pour cette classe est ci-dessous

 public class JsonSsortingngResult : JsonResult { public JsonSsortingngResult(ssortingng data) { JsonRequestBehavior = JsonRequestBehavior.DenyGet; Data = data; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && Ssortingng.Equals(context.HttpContext.Request.HttpMethod, "GET", SsortingngComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Get request is not allowed!"); } HttpResponseBase response = context.HttpContext.Response; if (!Ssortingng.IsNullOrEmpty(ContentType)) { response.ContentType = ContentType; } else { response.ContentType = "application/json"; } if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } if (Data != null) { response.Write(Data); } } } 

Exemple d’utilisation:

 var json = JsonConvert.SerializeObject(data); return new JsonSsortingngResult(json);