返回来自WebAPI的数据的json表示,没有强类型的IEnumerable

时间:2016-12-01 14:56:53

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

阅读了大量不同的解决方案并尝试了不同的方法(hereherehereherehere),我得到了来自API控制器的不同(和意外)结果。

我需要通过web api控制器返回表示为JSON的数据表:

[IdentityBasicAuthentication]
[Authorize]
[RequireHttps]
[Route("Reports/Report1")]
public HttpResponseMessage Get()
{
    DataTable dt = MyDAL.GetDataTable();
    if(someValidationFailed){
        Request.CreateResponse(HttpStatusCode.BadRequest, "Friendly error here");
    }
    return Request.CreateResponse(HttpStatusCode.OK, Newtonsoft.Json.JsonConvert.SerializeObject(dt));
}

在Fiddler中,输出似乎被编码为转义字符串:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

"[{\"Site\":\"Headquarters\",\"Department\":\"HR\",\"FirstName\":\"Bob\",\"MiddleName\":null,\"Surname\":\"Fern\",\"EmployeeNumber\":\"444\"},
{\"Site\":\"Headquarters\",\"Department\":\"HR\",\"FirstName\":\"Alice\",\"MiddleName\":null,\"Surname\":\"Smith\",\"EmployeeNumber\":\"769\"}]"

但是,目标是输出普通的Json(如果客户端请求它,则输出XML):

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[{"Site":"Headquarters","Department":"HR","FirstName":"Bob","MiddleName":null,"Surname":"Fern","EmployeeNumber":"444"},
{"Site":"Headquarters","Department":"HR","FirstName":"Alice","MiddleName":null,"Surname":"Smith","EmployeeNumber":"769"}]

有没有办法在不创建IEnumerable<Person>对象的情况下执行此操作?原因是这个类特定于这一个方法。我也不想使用StringBuilder,因为DataTable可能非常大,而且我之前已经看过内存异常。

我是WebAPI的新手,所以答案可能非常简单,但我可以提出进一步问题的代码示例会非常有用。

2 个答案:

答案 0 :(得分:9)

Web API为您处理序列化,因此您无需致电JsonConvert.SerializeObject。这就是为什么你得到一个转义字符串作为输出值。只需将数据表直接传递给CreateResponse即可。 Web API会根据请求的Accept标头中发送的内容将其转换为JSON或XML。 (它使用了Json.Net。)

return Request.CreateResponse(HttpStatusCode.OK, dt);

答案 1 :(得分:1)

使用匿名类型。 JSON支持匿名类型的序列化。

var persons = datatable.AsEnumerable()
                       .Select(datarow => new 
                       { 
                           Site = datarow.Field<string>("Site")
                       });

return Request.CreateResponse(HttpStatusCode.OK,
                              Newtonsoft.Json.JsonConvert.SerializeObject(persons));