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

时间:2014-08-05 18:12:14

标签: c# asp.net-web-api json.net

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

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

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

我们更新了c#方法,使用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;
}

resp var将以字符串类型的形式返回:

"{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对象,而不是任何字符串类型。

谢谢。

鲍勃

------------ UPDATE ----------------

通过拦截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

3 个答案:

答案 0 :(得分:27)

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,现在它是有效的......

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

这里发生的事情的关键在于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"}