如何在ASP.NET Web API 2中实现JSON垂直格式化输出
我搭建了一个ASP.NET Web API 2项目,尝试以JSON格式返回数据,但在Google Chrome中显示为无缩进的单行结构,同时出现「此XML文件似乎没有关联的样式信息」提示。我期望得到带缩进的垂直结构化JSON格式。
当前Chrome显示效果
This XML file does not appear to have any style information associated with it. The document tree is shown below. [{"UserId":23,"Name":"Emily","Access":3,"Mobile":"07419231"},{"UserId":31,"Name":"Lydia","Access":5,"Mobile":"67567587"},{"UserId":45,"Name":"Peter","Access":1,"Mobile":"90345853"},{"UserId":56,"Name":"Lebron","Access":4,"Mobile":"43895449"},{"UserId":73,"Name":"Amber","Access":0,"Mobile":"45788477"}]
期望的JSON格式
[ { "UserId":23, "Name":"Emily", "Access":3, "Mobile":"07419231" }, { "UserId":31, "Name":"Lydia", "Access":5, "Mobile":"67567587" }, { "UserId":45, "Name":"Peter", "Access":1, "Mobile":"90345853" }, { "UserId":56, "Name":"Lebron", "Access":4, "Mobile":"43895449" }, { "UserId":73, "Name":"Amber", "Access":0, "Mobile":"45788477" } ]
我的实现代码
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Data; using System.Data.SqlClient; using Newtonsoft.Json; namespace ApiTesting.Controllers { public class TestController : ApiController { SqlConnection con = new SqlConnection(@"server=DESKTOP-US2AF5N; database=Test; integrated security=true;"); public string Get() { SqlDataAdapter da = new SqlDataAdapter("Select * From TblDraft", con); DataTable dt = new DataTable(); da.Fill(dt); if (dt.Rows.Count > 0) { return JsonConvert.SerializeObject(dt); } else { return "No Data Found"; } } } }
问题根源有两点:一是方法返回string类型时,Web API默认会将内容包装为XML返回,导致Chrome识别为XML文件;二是直接序列化的JSON字符串未开启缩进格式。以下是几种解决方式:
方法一:直接返回格式化JSON对象
修改控制器方法返回类型为IHttpActionResult,使用Json()方法返回数据,该方法会自动输出格式化JSON并正确设置Content-Type为application/json:
public IHttpActionResult Get() { SqlDataAdapter da = new SqlDataAdapter("Select * From TblDraft", con); DataTable dt = new DataTable(); da.Fill(dt); if (dt.Rows.Count > 0) { return Json(dt); } else { return Ok("No Data Found"); } }
方法二:全局配置默认返回格式化JSON
如果希望所有接口都返回格式化JSON,可在WebApiConfig.cs中添加全局配置:
using System.Web.Http; using Newtonsoft.Json; namespace ApiTesting { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API路由配置 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // 开启JSON缩进格式化 config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; // 移除XML格式化器,默认返回JSON config.Formatters.Remove(config.Formatters.XmlFormatter); } } }
方法三:手动序列化并指定响应类型
若坚持使用JsonConvert.SerializeObject,可指定格式化参数并手动设置响应的Content-Type:
public HttpResponseMessage Get() { SqlDataAdapter da = new SqlDataAdapter("Select * From TblDraft", con); DataTable dt = new DataTable(); da.Fill(dt); string json; if (dt.Rows.Count > 0) { json = JsonConvert.SerializeObject(dt, Formatting.Indented); } else { json = "\"No Data Found\""; } var response = new HttpResponseMessage(HttpStatusCode.OK); response.Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); return response; }
内容的提问来源于stack exchange,提问作者user19613128

