【问题标题】:Return json representations of data from WebAPI without strongly-typed IEnumerable从没有强类型 IEnumerable 的 WebAPI 返回数据的 json 表示
【发布时间】:2017-04-16 06:37:15
【问题描述】:

阅读了大量不同的解决方案并尝试了不同的方法(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 的新手,所以答案可能非常简单,但我可以提出更多问题的代码示例会很有帮助。

【问题讨论】:

  • Web API 为您处理序列化,因此您无需调用JsonConvert.SerializeObject。这就是为什么你得到一个转义字符串作为你的返回值。
  • 好的,请问有什么方法可以获取 Json/Xml 格式的 DataTable?我对此很陌生,很容易混淆。
  • 只需将数据表传递给CreateResponse。 Web API 将根据在请求的 Accept 标头中发送的内容为您将其转换为 JSON 或 XML。 return Request.CreateResponse(HttpStatusCode.OK, dt);
  • 天哪,我不相信——你是对的,确实如此。我在别处读到返回 DataTable 包括 .Net 框架特定的数据。两天阅读不同的“解决方案”,我什至不需要费心。谢谢!

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


【解决方案1】:

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

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

【讨论】:

  • 我读到这样做还包括大量 .Net 框架数据(例如键、关系等),这就是我在其他地方阅读的原因。
  • 哈哈,不用担心;很高兴我能帮上忙。
【解决方案2】:

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

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

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

【讨论】:

  • 我(可能不正确)将datatable 更改为dt 以匹配我的变量名,但随后VS 说,datarow 在当前上下文中不存在
  • 这是 lambda 表达式 - 它必须是 datarow =&gt; new ...
  • 谢谢。下一个错误在return 行,无法将类型'System.Web.Http.Results.OkNegotiatedContentResult>>' 隐式转换为'字符串' 我尝试创建return Request.CreateResponse(HttpStatusCode.OK, persons),但也没有用
  • 使用您的代码 - 仅将序列化对象更改为 persons。对不起,我错误地使用了另一种方法。
猜你喜欢
  • 2015-10-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
相关资源
最近更新 更多