如何从C#方法返回Json对象

我正在尝试修复需要Json响应的ASP.NET WebAPI方法。 但是它会返回一个字符串。

最初它是在撤回XML格式,但我已将此行添加到App_Start \ WebApiConfig.cs中的mvc代码中,以便默认返回Json。

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

我们使用NewtonSoft更新了c#方法如下:

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

resp var以字符串类型的forms返回:

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

和jsonresp var看起来像这样:

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

在Chrome的F12开发工具中,数据对象是:

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

在Console工具中,angular.fromJson(data)的结果:

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

我将不胜感激如何正确返回Json对象,而不是任何字符串类型。

谢谢。

短发

————更新—————-

通过拦截resp var,并使用Chu先生的建议,我可以成功地在客户端上实现一个漂亮干净的Json对象。 关键是resp需要包含两个键:值对的双引号:

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

在Chrome控制台中,响应是:

 Object {status: "SUCCESS", data: Array[1]} data: Array[1] status: "SUCCESS" __proto__: Object 

resp已经是一个JSON字符串,但它不是有效的JSON(键没有用引号( " )包装。如果它返回到angular,JavaScript JSON.parse()方法无法反序列化它。但是,你可以使用JSON.NET将其反序列化为JObject并将其再次序列化为有效的JSON并创建自己的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; } 

或者您可以返回JObject并让Web API为您序列化它…

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

在任何一种情况下,Web API调用都应返回此JSON,现在该JSON有效…

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

在角度代码中,您必须挖掘出存储在名为data的数组中的会话ID …

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

我不知道这与AngularJS有什么关系,但你的问题很简单。 您的数据对象是JSON编码的。 所以你几乎可以肯定访问data.JsonRequestBehavior ,它将是1 。 但是它里面的数据字段是AGAIN JSON编码的。 你需要在尝试使用它之前解码它 – 当你得到这个回调时它只是一个字符串:

 var myData = angular.fromJson(data.Data); console.log(myData.data); 

请注意,您的data.Data对象本身就是另一个包装器 – 一个数组。 你几乎肯定希望myData.data[0]进入那个sessionID字段……

这里发生的事情的关键在于Mike Cheel的评论; 序列化发生了两次,一次在OP的代码中,一次在Asp.Net WebAPI 。 这就是返回字符串而不是Json对象的原因。

我遇到了完全相同的事情。 这是一个显示问题的hello world示例。 我先做了这样的事:

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

然后我尝试这样的事情,认为我需要返回IHttpActionResult来解决这个问题:

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

这两个控制器动作都给了我一个字符串而不是我想要的Json对象; 所以我去了:

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

最后我看到Mike的评论,并意识到我需要直接返回.Net对象,让WebAPI处理序列化。 所以不要回复这个:

 return Ok(JsonConvert.SerializeObject(result)); 

归还这个:

 return Ok(result); 

然后我得到了我期待的结果:

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