Web API 2:如何使用camelCased属性名称,对象及其子对象返回JSON

UPDATE

感谢所有的答案。 我正在一个新的项目上,看起来终于到了这个底部了:看起来下面的代码实际上是指责:

public static HttpResponseMessage GetHttpSuccessResponse(object response, HttpStatusCode code = HttpStatusCode.OK) { return new HttpResponseMessage() { StatusCode = code, Content = response != null ? new JsonContent(response) : null }; } 

别处…

  public JsonContent(object obj) { var encoded = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } ); _value = JObject.Parse(encoded); Headers.ContentType = new MediaTypeHeaderValue("application/json"); } 

我忽略了看上去无害的JsonContent,假设它是WebAPI而不是。

这是用在任何地方 …我可以只是第一个说,跆拳道? 也许这应该是“他们为什么要这样做?”


原来的问题如下

有人会认为这将是一个简单的configuration设置,但它现在已经躲过了我太久了。

我已经看了各种解决scheme和答案:

https://gist.github.com/rdingwall/2012642

似乎并不适用于最新的WebAPI版本…

以下似乎不工作 – 属性名称仍然是PascalCased。

  var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; json.UseDataContractJsonSerializer = true; json.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Mayank的答案在这里: CamelCase JSON WebAPI子对象(嵌套对象,子对象)似乎是一个不满意,但可行的答案,直到我意识到这些属性将不得不被添加到生成的代码,因为我们正在使用linq2sql …

任何方式自动做到这一点? 这个“讨厌”现在困扰了我很长一段时间。

把它放在一起,你会得到…

 protected void Application_Start() { HttpConfiguration config = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false; } 

这对我来说是有效的:

 internal static class ViewHelpers { public static JsonSerializerSettings CamelCase { get { return new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; } } } 

接着:

 [HttpGet] [Route("api/campaign/list")] public IHttpActionResult ListExistingCampaigns() { var domainResults = _campaignService.ListExistingCampaigns(); return Json(domainResults, ViewHelpers.CamelCase); } 

CamelCasePropertyNamesContractResolver来自Json.NET库中的Newtonsoft.Json.dll

事实certificate

 return Json(result); 

是罪魁祸首,导致序列化过程忽略camelcase设置。 然后

 return Request.CreateResponse(HttpStatusCode.OK, result, Request.GetConfiguration()); 

是我正在寻找的机器人。

 json.UseDataContractJsonSerializer = true; 

在工作中放了一把扳手,竟然不是我一直在寻找的机器人。

Owin Hosting和Ninject,上述所有答案都不适用于我。 以下是对我有用的东西:

 public partial class Startup { public void Configuration(IAppBuilder app) { // Get the ninject kernel from our IoC. var kernel = IoC.GetKernel(); var config = new HttpConfiguration(); // More config settings and OWIN middleware goes here. // Configure camel case json results. ConfigureCamelCase(config); // Use ninject middleware. app.UseNinjectMiddleware(() => kernel); // Use ninject web api. app.UseNinjectWebApi(config); } /// <summary> /// Configure all JSON responses to have camel case property names. /// </summary> private void ConfigureCamelCase(HttpConfiguration config) { var jsonFormatter = config.Formatters.JsonFormatter; // This next line is not required for it to work, but here for completeness - ignore data contracts. jsonFormatter.UseDataContractJsonSerializer = false; var settings = jsonFormatter.SerializerSettings; #if DEBUG // Pretty json for developers. settings.Formatting = Formatting.Indented; #else settings.Formatting = Formatting.None; #endif settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } } 

主要区别是:新的HttpConfiguration()而不是GlobalConfiguration.Configuration。

WebApiConfig代码:

  public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //This line sets json serializer's ContractResolver to CamelCasePropertyNamesContractResolver, // so API will return json using camel case config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } } 

确保你的API操作方法以下面的方式返回数据,并且你已经安装了最新版本的Json.Net/Newtonsoft.Json Installed:

  [HttpGet] public HttpResponseMessage List() { try { var result = /*write code to fetch your result*/; return Request.CreateResponse(HttpStatusCode.OK, cruises); } catch (Exception ex) { return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message); } } 

这是一个晦涩的,当路由属性不匹配的GET url,但GET url匹配方法的名称,jsonserializer骆驼案指令将被忽略,例如

HTTP://网站/ API /地理/地理

 //uppercase fail cakes [HttpGet] [Route("countries")] public async Task<GeoData> GeoData() { return await geoService.GetGeoData(); } //lowercase nomnomnom cakes [HttpGet] [Route("geodata")] public async Task<GeoData> GeoData() { return await geoService.GetGeoData(); } 

我用Breeze使用WebApi,当我尝试在微风控制器中执行一个非微妙的操作时,我遇到了同样的问题。 我尝试使用App.GetConfiguration而不是相同的结果。 所以,当我访问Request.GetConfiguration返回的对象时,我意识到请求使用的序列化是微风服务器使用它的魔术。 任何方式,我解决了我的问题创build一个不同的HttpConfiguration:

 public static HttpConfiguration BreezeControllerCamelCase { get { var config = new HttpConfiguration(); var jsonSerializerSettings = config.Formatters.JsonFormatter.SerializerSettings; jsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false; return config; } } 

并将其作为Request.CreateResponse中的parameter passing如下:

 return this.Request.CreateResponse(HttpStatusCode.OK, result, WebApiHelper.BreezeControllerCamelCase); 

在你的Owin Startup中添加这行…

  public class Startup { public void Configuration(IAppBuilder app) { var webApiConfiguration = ConfigureWebApi(); app.UseWebApi(webApiConfiguration); } private HttpConfiguration ConfigureWebApi() { var config = new HttpConfiguration(); // ADD THIS LINE HERE AND DONE config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.MapHttpAttributeRoutes(); return config; } } 

我已经解决了以下方法。

 [AllowAnonymous] [HttpGet()] public HttpResponseMessage GetAllItems(int moduleId) { HttpConfiguration config = new HttpConfiguration(); config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false; try { List<ItemInfo> itemList = GetItemsFromDatabase(moduleId); return Request.CreateResponse(HttpStatusCode.OK, itemList, config); } catch (System.Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message); } }