Jak mogę zmienić nazwy właściwości podczas serializacji z Json.net?

434

Mam trochę danych w obiekcie C # DataSet. Mogę teraz serializować to za pomocą takiego konwertera Json.net

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

Jednak używa to nazw właściwości z datapodczas drukowania do pliku .json. Chciałbym zmienić nazwy właściwości na coś innego (powiedzmy, zmień „foo” na „bar”).

W dokumentacji Json.net w części „Serializacja i deserializacja JSON” → „Atrybuty serializacji” jest napisane: „JsonPropertyAttribute ... pozwala na dostosowanie nazwy”. Ale nie ma przykładu. Czy ktoś wie, jak użyć JsonPropertyAttribute do zmiany nazwy właściwości na coś innego?

( Bezpośredni link do dokumentacji )

Dokumentacja Json.net wydaje się rzadka. Jeśli masz świetny przykład, postaram się go dodać do oficjalnej dokumentacji. Dzięki!

culix
źródło
3
Do Twojej dyspozycji jest przykład tego w dokumentacji w części Próbki -> Serializacja JSON -> JsonPropertyAttribute nazwa . Nie jestem pewien, w którym momencie został dodany.
Brian Rogers,

Odpowiedzi:

791

Możesz ozdobić właściwość, którą chcesz kontrolować, jej nazwą za pomocą [JsonProperty]atrybutu, który pozwala określić inną nazwę:

using Newtonsoft.Json;
// ...

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

Dokumentacja: atrybuty serializacji

Darin Dimitrov
źródło
1
Czy wymaga to odczytania moich danych do niestandardowego obiektu, który tworzę, a nie zestawu danych?
culix
3
@culix, tak, wymaga użycia modelu. Zestaw danych jest słabo typowaną strukturą, dlatego mówienie o nazwach właściwości nie jest zbyt logiczne.
Darin Dimitrov
76
[JsonProperty("FooBar")]
Krótko mówiąc
2
@DarinDimitrov czy istnieje sposób, aby to zrobić bez Json .NET?
CH81,
12
Korzystanie z modelu jest łatwe, wystarczy pobrać próbkę JSON i wkleić do pustego pliku .cs, używając opcji „Wklej specjalnie” -> „Wklej JSON jako klasy”. - Jest wbudowany w Visual Studio. - Stamtąd po prostu musisz skonfigurować rzeczy jako tytuł / zmieniaj nazwy, aby korzystać z konwencji nazewnictwa .NET itp. (Przy użyciu konwertera wielkości tytułów dla pierwszego i atrybutu JsonProperty dla drugiego).
BrainSlugs83 24.10.16
71

Jeśli nie masz dostępu do klas w celu zmiany właściwości lub nie chcesz zawsze używać tej samej właściwości zmiany nazwy, zmiany nazwy można również dokonać, tworząc niestandardowy program rozpoznawania nazw.

Na przykład, jeśli masz klasę o nazwie MyCustomObject, która ma właściwość o nazwie LongPropertyName, możesz użyć niestandardowego programu rozpoznawania nazw takiego jak…

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;
  }
}

Następnie wezwij do serializacji i podaj resolvera:

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

Wynik zostanie skrócony do {„Short”: „wartość prop”} zamiast {„LongPropertyName”: „wartość prop”}

Więcej informacji o niestandardowych rozwiązaniach tutaj

StingyJack
źródło
1
Jest to lepsze rozwiązanie, jeśli twoja klasa do serializacji jest zadeklarowana w innym zestawie, który zawiera inną wersję pakietu Newtonsoft.Json. (może nawet nie rzucić żadnego błędu). DefaultContractResolverMusi być umieszczone w tym samym zespole, gdzie jest stosowany sposób JsonConvert.Serialize ().
Artemious
6

Jest jeszcze inny sposób, aby to zrobić, używając określonej NamingStrategy , którą można zastosować do klasy lub właściwości, dekorując je za pomocą [JSonObject]lub [JsonProperty].

Istnieją predefiniowane strategie nazewnictwa, takie jak CamelCaseNamingStrategy, ale możesz wdrożyć własne.

Implementację różnych strategii nazewnictwa można znaleźć tutaj: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization

JotaBe
źródło
3
Jeśli możesz, udostępnij przykład niestandardowej implementacji
NamingStrategy
Oczywiście nie. Powinieneś to zrobić sam, ale oszczędzę ci czasu, aby powiedzieć, że po prostu musisz odziedziczyć newtonsoft.com/json/help/html/... Możesz zobaczyć istniejącą implementację klas i stworzyć własną.
JotaBe,
Dzięki - powinienem był zaktualizować swój komentarz: w rzeczywistości, dzięki chwale, którą jest GitHub, można użyć jednej z własnych implementacji Newtonsoft jako przykładu, powiedzmy, ten
user1007074
8
@JotaBe, to nie jest duch przepełnienia stosu. A jako programista, który chce po prostu wykonać moją pracę, szczerze mówiąc, byłoby tysiąc razy lepiej dla mnie, aby podnieść kod, który mogłeś podać. Ty też miałbyś mój głos. Mam 18-letnie doświadczenie w programowaniu i jestem klasyfikowany przez TripleByte jako „ekspert” w języku c #. Nie KAŻDY problem należy pozostawić jako „ćwiczenie dla czytelnika”. Czasami chcemy po prostu wykonać naszą pracę i przejść dalej.
bboyle1234
2
Zgadzam się z tobą i zwykle nie piszę tego rodzaju komentarzy. Mogę jednak zapewnić, że w tym przypadku przeglądanie połączonego kodu jest znacznie lepsze niż jakiekolwiek wyjaśnienie, które mogę podać. A json.net to bardzo dobrze udokumentowana biblioteka open source. Zawarty link do implementacji (doskonałe przykłady)
JotaBe