Як я можу змінити імена властивостей під час серіалізації з Json.net?


434

У мене є деякі дані в об'єкті C # DataSet. Я можу серіалізувати його прямо зараз, використовуючи подібний конвертер Json.net

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

Однак для цього використовуються імена властивостей від dataдруку до файлу .json. Я хотів би змінити назви властивостей на щось інше (скажімо, змінити "foo" на "bar").

У документації на Json.net у розділі "Серіалізація та десеріалізація JSON" → "Атрибути серіалізації" написано "JsonPropertyAttribute ... дозволяє налаштувати ім'я". Але прикладу немає. Хтось знає, як за допомогою JsonPropertyAttribute змінити ім’я властивості на щось інше?

( Пряме посилання на документацію )

Документація Json.net здається рідкою. Якщо у вас є чудовий приклад, я спробую додати його до офіційної документації. Дякую!


3
FYI, є приклад цього в документації під зразками -> серіалізація JSON -> ім'я JsonPropertyAttribute . Не впевнений, в який момент він був доданий.
Брайан Роджерс

Відповіді:


791

Ви можете прикрасити властивість, яку ви хочете контролювати її ім'ям [JsonProperty]атрибутом, який дозволяє вказати інше ім'я:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

Документація: атрибути серіалізації


1
Чи потрібно це, щоб я читав свої дані в користувальницький об’єкт, який я створюю, а не DataSet?
culix

3
@culix, так, це вимагає використання моделі. DataSet - це слабо набрана структура, тому говорити про назви властивостей для неї не дуже логічно.
Дарин Димитров

76
Як скорочення, ви також можете це зробити[JsonProperty("FooBar")]
Барт Веркойейн

2
@DarinDimitrov є спосіб зробити це без Json .NET?
CH81

12
Використовувати модель дуже просто, просто візьміть зразок свого JSON і вставте його в порожній .cs-файл, використовуючи "Вставити спеціальний" -> "Вставити JSON як класи". - Він вбудований у Visual Studio. - Звідси вам просто потрібно налаштувати речі в якості заголовка / перейменування речей для використання конвенцій.
BrainSlugs83

71

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

Наприклад, якщо у вас є клас MyCustomObject, який називається , у якого є властивість, що називається LongPropertyName, ви можете скористатися користувальницьким розв'язувачем на зразок цього ...

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

Потім закликайте до серіалізації та надайте роздільну здатність:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

І результат буде скорочено до {"Short": "value value"} замість {"LongPropertyName": "value prop"}

Більше інформації про власні розв’язувачі тут


1
Це краще рішення, якщо ваш клас для серіалізації оголошено в іншій збірці, що включає іншу версію пакету Newtonsoft.Json. (це може навіть не призвести до помилки). DefaultContractResolverПовинен бути поміщений в тій же збірці , де використовується метод JsonConvert.Serialize ().
Артемічний

6

Існує ще один спосіб зробити це, використовуючи певний NamingStrategy , який можна застосувати до класу чи властивості, прикрасивши їх за допомогою [JSonObject]або [JsonProperty].

Існують заздалегідь визначені стратегії іменування на кшталт CamelCaseNamingStrategy, але ви можете реалізувати власні.

Реалізацію різних стратегій іменування можна знайти тут: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization


3
Якщо у вас є можливість, будь ласка, поділіться прикладом спеціальної реалізації
NamingStrategy

Звичайно, ні. Ви повинні були зробити це самостійно, але я шкодую вам час, щоб сказати вам, що вам просто потрібно успадкувати newtonsoft.com/json/help/html/… Ви можете побачити існуючу реалізацію класів та створити свою власну.
JotaBe

Дякую - я мав би оновити свій коментар: насправді, завдяки славі GitHub, можна використовувати одну із власних реалізацій Newtonsoft як приклад, скажімо, цю
user1007074

8
@JotaBe, це не дух stackoverflow. І як програміст, який просто хоче виконати свою роботу, відверто кажучи, мені було б в тисячу разів краще зняти код, який ви могли б надати. І ти також отримав би мій голос. Я маю 18 років досвіду кодування, і мене оцінюють TripleByte як "експерта" в c #. НЕ КОЖУ проблему потрібно залишати як "вправу для читача". Іноді ми просто хочемо зробити свою роботу і рухатися далі.
bboyle1234

2
Я згоден з вами, і я зазвичай не пишу такого роду коментарі. Однак я можу запевнити, що в цьому випадку перегляд пов'язаного коду є набагато кращим, ніж будь-яке пояснення, яке я можу дати. І json.net - це дуже добре задокументована бібліотека з відкритим кодом. Включено посилання на реалізації (ідеальні приклади)
JotaBe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.