MVC: how to return a string in JSON

To make the progress report process a little more reliable and separate it from the request / response, I perform the processing in the Windows service and save the intended response to the file. When the client starts polling for updates, it is assumed that the controller returns the contents of the file, regardless of what they are, like a JSON string.

The contents of the file are pre-serialized in JSON. This should ensure that there is nothing in the way of the answer. No processing should happen (without reading the contents of the file in a line and returning it) to get an answer.

I originally, although it would be quite simple, but it is not.

Currently, my controller method is as follows:

Controller

Update

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

And Fiddler returns this as a raw answer

 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

Update

Further, most likely, it will be changed later, but for now it works when I generate a response class and return it as JSON, as an ordinary person.

 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; } } 
+62
json asp.net-mvc
Mar 19 '12 at 20:50
source share
5 answers

I believe that the problem is that the result of the Json action is intended to take an object (your model) and create an HTTP response with the content in the form of data in JSON format from your model object.

What you pass to the Json controller, however, is a string object in JSON format, so it "serializes" the JSON string object, so the contents of the HTTP response are surrounded by double quotes (I assume this is a problem).

I think you can examine the result of the Content action as an alternative to the action Json result, since you essentially already have the raw content for the HTTP response.

 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 

Another alternative would be to deserialize the JSON result from the service into an object and then pass that object to the Json method of the controller, but the disadvantage is that you will de-serialize and then re-serialize the data, which may be unnecessary for your purposes.

+110
Mar 19 '12 at 21:01
source share

You just need to return the default ContentResult and set the ContentType to "application / json". You can create a custom ActionResult for it:

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

And then return the instance:

 [HttpPost] public JsonResult UpdateBatchSearchMembers() { string returntext; if (!System.IO.File.Exists(path)) returntext = Properties.Settings.Default.EmptyBatchSearchUpdate; else returntext = Properties.Settings.Default.ResponsePath; return new JsonStringResult(returntext); } 
+39
Mar 19 2018-12-12T00:
source share

Yes, it is without any additional problems to avoid raw string json, this is it.

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

NOTE: note that the return type of the JsonResult method does not work for me, since JsonResult and ContentResult both inherit ActionResult , but there is no relationship between them.

+2
Jun 12 '17 at 4:59
source share

All answers here give good and working code. But someone will be unhappy that they all use ContentType as the return type, not JsonResult .

Unfortunately, JsonResult uses a JavaScriptSerializer without the ability to disable it. The best way around this is to inherit JsonResult .

I copied most of the code from the original JsonResult and created a JsonStringResult class that returns the passed string as application/json . The code for this class is below.

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

Usage example:

 var json = JsonConvert.SerializeObject(data); return new JsonStringResult(json); 
0
Apr 24 '18 at 10:53
source share

from the controller:

return Json (new {success = string}, JsonRequestBehavior.AllowGet);

and if successful, Javascript: function (data) {var response = data.success;

0
Apr 03 '19 at 21:40
source share



All Articles