Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a Json object from a C# method

Tags:

I am trying to fix an ASP.NET WebAPI method where a Json response is required. However it's returning a string instead.

Initially it was returing XML format, but I've added this line to the mvc code in App_Start\WebApiConfig.cs in order to return Json by default.

config.Formatters.Remove(config.Formatters.XmlFormatter); 

We've updated the c# method as follows to use NewtonSoft:

public string Get() {     string userid = UrlUtil.getParam(this, "userid", "");     string pwd = UrlUtil.getParam(this, "pwd", "");     string resp = DynAggrClientAPI.openSession(userid, pwd);      JsonSerializer ser = new JsonSerializer();     string jsonresp = JsonConvert.SerializeObject(resp);      return resp; } 

The resp var is coming back as a string type:

"{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}" 

and jsonresp var looks like this :

"\"{status:\\\"SUCCESS\\\",data:[\\\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\\\"]}\"" 

and in Chrome's F12 dev tools, the data object is :

""{status:\"SUCCESS\",data:[\"4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d\"]}"" 

and in Console tools, the result of angular.fromJson(data) :

"{status:"SUCCESS",data:["4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d"]}" 

I would appreciate some advice on how to properly return the Json object, and NOT in any string type.


UPDATE

By intercepting the resp var, and using Mr. Chu's suggestion below, I can successfully achieve a nice clean Json object on the client. The key is that resp needs to contains double quotes around both key:value pairs:

public HttpResponseMessage Get() {     string userid = UrlUtil.getParam(this, "userid", "");     string pwd = UrlUtil.getParam(this, "pwd", "");     string resp = DynAggrClientAPI.openSession(userid, pwd);      resp = "{\"status\":\"SUCCESS\",\"data\":[\"194f66366a6dee8738428bf1d730691a9babb77920ec9dfa06cf\"]}";  // TEST !!!!!                 var response = Request.CreateResponse(HttpStatusCode.OK);     response.Content = new StringContent(resp, System.Text.Encoding.UTF8, "application/json");     return response; } 

in Chrome console, the response is :

Object {status: "SUCCESS", data: Array[1]} data: Array[1] status: "SUCCESS" __proto__: Object 
like image 393
bob.mazzo Avatar asked Aug 05 '14 18:08

bob.mazzo


People also ask

How do I return a JSON response?

To return JSON from the server, you must include the JSON data in the body of the HTTP response message and provide a "Content-Type: application/json" response header. The Content-Type response header allows the client to interpret the data in the response body correctly.

Can we return JSON through Viewresult?

@Zach Yes, It's possible. You can return your html with model.

What is JSON return type?

JsonResult is an ActionResult type in MVC. It helps to send the content in JavaScript Object Notation (JSON) format.


2 Answers

resp is already a JSON string, but it is not valid JSON (the keys are not wrapped in quotes ("). If it is returned to angular, the JavaScript JSON.parse() method is unable to deserialize it. However, you can use JSON.NET in deserialize it to a JObject and serialize it again into valid JSON and create your own HttpResponseMessage...

public HttpResponseMessage Get() {     string userid = UrlUtil.getParam(this, "userid", "");     string pwd    = UrlUtil.getParam(this, "pwd", "" );      string resp = DynAggrClientAPI.openSession(userid, pwd);     var jObject = JObject.Parse(resp);      var response = Request.CreateResponse(HttpStatusCode.OK);     response.Content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");     return response; } 

Or you can just return the JObject and have Web API serialize it for you...

public JObject Get() {     string userid = UrlUtil.getParam(this, "userid", "");     string pwd    = UrlUtil.getParam(this, "pwd", "" );      string resp = DynAggrClientAPI.openSession(userid, pwd);     var jObject = JObject.Parse(resp);      return jObject; } 

In either case, the Web API call should return this JSON, which is now valid...

{   "status": "SUCCESS",   "data": [     "4eb97d2c6729df98206cf214874ac1757649839fe4e24c51d21d"   ] } 

In the angular code, you'd have to dig out the session id which is stored in an array called data...

userService.openUserSession(rzEnvJson).then(function (response) {     var sessionResponse = response.data; // or simply response, depending if this is a promise returned from $http     $rootScope.rgSessionVars.sessionID = sessionResponse.data[0]; }); 
like image 59
Anthony Chu Avatar answered Sep 27 '22 21:09

Anthony Chu


The key to what is going on here is in the comment made by Mike Cheel; serialization is happening twice, once in the OP's code and once by Asp.Net WebAPI. That is why a string is returned instead of a Json object.

I was encountering the exact same thing. Here is a hello world example showing the problem. I first did something like this:

[Route("getall")] public string GetAllItems() {     var result = new     {         x = "hello",         y = "world"     };     return JsonConvert.SerializeObject(result); } 

I then tried to so something like this, thinking that I needed to return IHttpActionResult to resolve this:

[Route("getall")] public IHttpActionResult GetAllItems() {     var result = new     {         x = "hello",         y = "world"     };     return Ok(JsonConvert.SerializeObject(result)); } 

Both these controller actions gave me a string rather than the Json object that I was wanting; so I go this:

"{\"x\":\"hello\",\"y\":\"world\"}" 

Finally I saw the comment by Mike and realized that I needed to return the .Net object directly and just let WebAPI handle the serialization. So instead of returning this:

return Ok(JsonConvert.SerializeObject(result)); 

return this:

return Ok(result); 

Then I got the result that I was expecting:

{"x":"hello","y":"world"} 
like image 30
BruceHill Avatar answered Sep 27 '22 21:09

BruceHill