Web API 2: как вернуть JSON с именами свойств camelCased, на объекты и их под-объекты

ОБНОВИТЬ

Спасибо за ответы на все вопросы. Я нахожусь в новом проекте, и похоже, что я, наконец, дошел до конца: похоже, что на самом деле виноват следующий код:

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, но нет.

Это используется везде … Могу ли я просто сказать первым, wtf? Или, может быть, это должно быть «Почему они это делают?»


исходный вопрос

Можно было бы подумать, что это будет простая настройка конфигурации, но она слишком долго ускользает от меня.

Я рассмотрел различные решения и ответы:

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(); 

Ответ Майанка здесь: Sub-Objects 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 поступает из Newtonsoft.Json.dll в библиотеке Json.NET .

Все приведенные выше ответы не помогли мне с 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); } ///  /// Configure all JSON responses to have camel case property names. ///  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.

Оказывается, что

 return Json(result); 

был виновником, в результате чего процесс сериализации игнорировал настройку камеры. И это

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

был дроидом, которого я искал.

Также

 json.UseDataContractJsonSerializer = true; 

Ставил гаечный ключ в работах и ​​оказался НЕ дроидом, которого я искал.

Код 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 Action Method возвращает данные следующим образом, и вы установили последнюю версию 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); } } 

В своем 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; } } 

Вот неясный, когда атрибут маршрута не соответствует URL-адресу GET, но URL-адрес GET соответствует имени метода, директива case jsonserializer camel будет проигнорирована, например

Http: // сайт / апи / гео / геоданных

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

Я решил это следующими способами.

 [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 itemList = GetItemsFromDatabase(moduleId); return Request.CreateResponse(HttpStatusCode.OK, itemList, config); } catch (System.Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message); } } 

Я использую WebApi с Breeze, и я столкнулся с той же проблемой при попытке выполнить не-бриз-действие в controllerе Breeze. Я попытался использовать оценку Request.GetConfiguration, но тот же результат. Поэтому, когда я обращаюсь к объекту, возвращенному Request.GetConfiguration, я понимаю, что сериализатор, используемый по запросу, используется сервером breeze-server, чтобы сделать его магическим. В любом случае, я решил проблему, создав другую 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 следующим образом:

 return this.Request.CreateResponse(HttpStatusCode.OK, result, WebApiHelper.BreezeControllerCamelCase); 
  • Ошибка десериализации Newtonsoft JSON.net, где поля в порядке изменения JSON
  • JToken: получить исходное / оригинальное значение JSON
  • Json.Net - Сериализовать имя свойства без кавычек
  • Использование пользовательской десериализации тела WCF без изменения десериализации шаблона URI
  • Разбор массива JSON с использованием Json.Net
  • Не удалось загрузить файл или сборку «Newtonsoft.Json, Version = 4.5.0.0, Culture = neutral, PublicKeyToken = 30ad4fe6b2a6aeed»
  • Как использовать JSON.NET для десериализации в вложенный / рекурсивный словарь и список?
  • JSON.net сериализуется непосредственно из oledbconnection
  • Исключить свойство из сериализации через пользовательский атрибут (json.net)
  • Сериализовать словарь как массив (пар ключей)
  • C # WCF REST. Как вы используете сериализатор JSON.Net вместо стандартного DataContractSerializer?
  • Interesting Posts

    Как использовать std :: find / std :: find_if с вектором объектов пользовательского classа?

    Где ConfigurationGenerateSchemaCreationScript () переместился в Hibernate 5

    Обновление Windows 10 1511 с помощью шифрования всего диска DiskCryptor

    Как установить OSX Lion на Core Solo Mac Mini?

    получить абсолютный путь при выборе изображения из галереи kitkat android

    Как сохранить логическое значение с помощью SharedPreferences в Android?

    Что именно происходит, когда я устанавливаю LoadUserProfile пула IIS?

    Получение отдельного windows приложения текущего уровня громкости, как визуализируется в аудио Mixer

    Мой tcpdump всегда фильтрует пакеты?

    Ionic2 / Angular2 – прочитать пользовательский файл конфигурации

    Язык клавиатуры продолжает меняться в Windows 10

    Почему это иногда занимает много времени для закрытия окон?

    Как получить объект родительского базового classа super.getClass ()

    извлекать изображения из pdf с помощью pdfbox

    Как редактировать системный / пользовательский словарь в Windows 8?

    Давайте будем гением компьютера.