serialization - Hogyan lehet a JSON-protokoll használatával kezelni a legjobban?

Translate

Általában a kód minden részét C # -be írom, és sorosított protokollok írásakor a FastSerializer-t használom, amely gyorsan és hatékonyan sorosítja / deserializálja az osztályokat. Ez is nagyon könnyen használható, és meglehetősen egyszerű a "verziószámozás", azaz a szerializálás különböző verzióinak kezelése. A dolog, amit általában használok, így néz ki:

public override void DeserializeOwnedData(SerializationReader reader, object context)
{
    base.DeserializeOwnedData(reader, context);
    byte serializeVersion = reader.ReadByte(); // used to keep what version we are using

    this.CustomerNumber = reader.ReadString();
    this.HomeAddress = reader.ReadString();
    this.ZipCode = reader.ReadString();
    this.HomeCity = reader.ReadString();
    if (serializeVersion > 0)
        this.HomeAddressObj = reader.ReadUInt32();
    if (serializeVersion > 1)
        this.County = reader.ReadString();
    if (serializeVersion > 2)
        this.Muni = reader.ReadString();
    if (serializeVersion > 3)
        this._AvailableCustomers = reader.ReadList<uint>();
}

és

public override void SerializeOwnedData(SerializationWriter writer, object context)
{            
    base.SerializeOwnedData(writer, context);
    byte serializeVersion = 4; 
    writer.Write(serializeVersion);


    writer.Write(CustomerNumber);
    writer.Write(PopulationRegistryNumber);            
    writer.Write(HomeAddress);
    writer.Write(ZipCode);
    writer.Write(HomeCity);
    if (CustomerCards == null)
        CustomerCards = new List<uint>();            
    writer.Write(CustomerCards);
    writer.Write(HomeAddressObj);

    writer.Write(County);

    // v 2
    writer.Write(Muni);

    // v 4
    if (_AvailableCustomers == null)
        _AvailableCustomers = new List<uint>();
    writer.Write(_AvailableCustomers);
}

Tehát könnyű hozzáadni új dolgokat, vagy teljesen megváltoztatni a sorozatot, ha valaki úgy dönt.

Most azonban a JSON-t szeretném használni olyan okok miatt, amelyek itt nem relevánsak =) Jelenleg használomDataContractJsonSerializerés most azt a módot keresem, hogy ugyanolyan rugalmasságot biztosíthassak, mint a fenti FastSerializer segítségével.

Tehát a kérdés az; mi a legjobb módszer a JSON protokoll / sorozatosítás létrehozására és a fentiek szerinti részletezésre, hogy ne szakítsam meg a sorosítást csak azért, mert egy másik gép még nem frissítette a verziójukat?

This question and all comments follow the "Attribution Required."

Minden válasz

Translate

A JSON verziójának kulcsa az, hogy mindig új tulajdonságokat adjon hozzá, és soha ne távolítsa el vagy nevezze át a meglévő tulajdonságokat. Ez hasonló ahogy a protokollpufferek hogyan kezelik a verziószámot.

Például, ha a következő JSON-tal indult:

{
  "version": "1.0",
  "foo": true
}

És a "foo" tulajdonságot át akarja nevezni "bar" -ra, ne csak átnevezze. Ehelyett adjon hozzá egy új tulajdonságot:

{
  "version": "1.1",
  "foo": true,
  "bar": true
}

Mivel soha nem távolítja el a tulajdonságokat, a régebbi verziókon alapuló kliensek továbbra is működni fognak. Ennek a módszernek az a hátránya, hogy a JSON idővel felpuffadhat, és folytatnia kell a régi tulajdonságok fenntartását.

Fontos továbbá, hogy világosan meghatározza ügyfelei számára az „éles” eseteket. Tegyük fel, hogy rendelkezik egy "fooList" nevű tömb tulajdonsággal. A "fooList" tulajdonság a következő lehetséges értékeket veheti fel: nem létezik / nincs meghatározva (a tulajdonság fizikailag nincs a JSON objektumban, vagy létezik, és "undefined" értékre van állítva), null, üres lista vagy egy lista egy vagy több érték. Fontos, hogy az ügyfelek megértsék, hogyan kell viselkedni, különösen a nem definiált / null / üres esetekben.

Azt is javasolnám, hogy olvassa el, hogyanszemantikai változatművek. Ha szemantikus verziósémát vezet be a verziószámaiba, akkor visszafelé kompatibilis változtatásokat lehet végrehajtani egy kisebb verzióhatáron, míg a törésmódosításokat egy nagyobb verzióhatáron lehet végrehajtani (az ügyfeleknek és a szervereknek egyaránt meg kell állapodniuk ugyanazon fő verzióban) ). Bár ez nem a JSON tulajdonát képezi, ez hasznos a változások típusainak közlésére, amelyekre az ügyfélnek a verzióváltáskor számolnia kell.

Forrás
Translate

A Google java alapúgson könyvtárkiváló verziós támogatást nyújt a json számára. Nagyon hasznos lehet, ha java módon gondolkodsz.

Van egy szép és könnyű bemutatóitt.

Forrás
Translate

Ne használja a DataContractJsonSerializer alkalmazást, ahogy a neve mondja, az ezen osztályon keresztül feldolgozott objektumoknak:

a) Jelölje meg a [DataContract] és [DataMember] attribútumokkal.

b) Szigorúan be kell tartani a meghatározott "Szerződést", vagyis nem kevesebbet és többet, mint amit meghatároztak. Bármely extra vagy hiányzó [DataMember] kivételt képez a deszerializáció.

Ha elég rugalmas akar lenni, akkor használja a JavaScriptSerializer alkalmazást, ha az olcsó lehetőséget választja ... vagy használja ezt a könyvtárat:

http://json.codeplex.com/

Ez elegendő ellenőrzést biztosít a JSON-sorozatosítás felett.

Képzelje el, hogy van egy tárgya annak korai szakaszában.

public class Customer
{ 
    public string Name;

    public string LastName;
}

A sorosítást követően így fog kinézni:

{Név: "John", vezetéknév: "Doe"}

Ha megváltoztatja az objektum definícióját mezők hozzáadásához / eltávolításához. A deserializáció simán fog történni, ha például JavaScriptSerializer programot használ.

public class Customer
{ 
    public string Name;

    public string LastName;

    public int Age;
}

Ha megpróbálja megszüntetni az utolsó json sorosítását ebbe az új osztályba, akkor nem lesz hiba. Az a helyzet, hogy az új mezők az alapértelmezett értékekre lesznek beállítva. Ebben a példában: "Kor" nulla lesz.

Saját konvencióiban felvehet egy, az összes objektumában jelen lévő mezőt, amely tartalmazza a verziószámot. Ebben az esetben meg tudja különböztetni az üres mezőt vagy a verzió inkonzisztenciáját.

Tehát mondjuk: Az ügyfél v1 osztályú sorosított:

{ Version: 1, LastName: "Doe", Name: "John" }

Deserializálni kíván vevői v2 példányt, a következőkkel rendelkezik:

{ Version: 1, LastName: "Doe", Name: "John", Age: 0}

Valahogy meg tudja állapítani, hogy az objektumban mely mezők valahogy megbízhatóak és mi nem. Ebben az esetben tudja, hogy a v2 objektum példánya v1 objektum példányból származik, ezért az Age mezőt nem szabad megbízni.

Arra gondolok, hogy használjon egyéni attribútumot is, pl. "MinVersion", és minden mezőt jelöljön meg a minimálisan támogatott verziószámmal, így valami ilyesmit kap:

public class Customer
{ 
    [MinVersion(1)]
    public int Version;

    [MinVersion(1)]
    public string Name;

    [MinVersion(1)]
    public string LastName;

    [MinVersion(2)]
    public int Age;
}

Majd később elérheti ezeket a metaadatokat, és bármit megtehet, amire szüksége lehet.

Forrás
Translate

Nem számít, hogy milyen sorosítási protokollt használ, az API-k verziójának technikái általában megegyeznek.

Általában szükséged van:

  1. annak módja, hogy a fogyasztó közölje a gyártóval az általa elfogadott API verziót (bár ez nem mindig lehetséges)
  2. a gyártó módja annak, hogy a verziós információkat beágyazza a sorosított adatokba
  3. visszafelé kompatibilis stratégia az ismeretlen mezők kezelésére

Egy webes API-ban általában a fogyasztó által elfogadott API-verzió van beágyazva az Accept fejlécbe (plAccept: application/vnd.myapp-v1+json application/vnd.myapp-v2+jsonazt jelenti, hogy a fogyasztó képes kezelni az API 1. és 2. verzióját), vagy ritkábban az URL-ben (plhttps://api.twitter.com/1/statuses/user_timeline.json). Ezt általában a főbb verzióknál (azaz visszafelé inkompatibilis változásoknál) használják. Ha a kiszolgálónak és az ügyfélnek nincs megfelelő Accept fejlécje, akkor a kommunikáció meghiúsul (vagy a legjobb erőfeszítések alapján halad, vagy az alkalmazás jellegétől függően az alapértelmezett alapvonal protokollra áll vissza).

Ezután a gyártó létrehoz egy sorosított adatot a kért verzió egyikében, majd beágyazza ezt a verzióinformációt a sorosított adatokba (pl.version). A fogyasztónak az adatokba ágyazott verzióinformációk alapján kell meghatároznia a sorosított adatok elemzésének módját. Az adatokban szereplő verzióinformációknak tartalmazniuk kell kisebb verziókat is (azaz a kompatibilis változások visszamenőleges visszaállításához), általában a fogyasztóknak képesnek kell lenniük figyelmen kívül hagyni a kisebb verziós információkat és továbbra is helyesen feldolgozni az adatokat, bár a kisebb verzió megértése lehetővé teheti az ügyfél számára, hogy további feltételezéseket tegyen a következőkről: hogyan kell az adatokat feldolgozni.

Az ismeretlen mezők kezelésének általános stratégiája például a HTML és a CSS elemzése. Amikor a fogyasztó ismeretlen mezőket lát, figyelmen kívül kell hagynia, és ha az adatokból hiányzik egy mező, amelyre az ügyfél számít, akkor alapértelmezett értéket kell használnia; A kommunikáció jellegétől függően érdemes megadnia néhány kötelező mezőt (azaz a hiányzó mezők végzetes hibának számítanak). A kisebb verziókon belül hozzáadott mezőknek mindig választható mezőknek kell lenniük; A kisebb verzió hozzáadhat opcionális mezőket vagy megváltoztathatja a szemantikus mezőket, amennyiben kompatibilisek a visszafelé, míg a fő verziók törölhetnek mezőket, vagy kötelező mezőket adhatnak hozzá, vagy a szemantikus mezőket visszafelé inkompatibilis módon módosíthatják.

Bővíthető sorosítási formátumban (például JSON vagy XML) az adatoknak önleíróaknak kell lenniük, más szóval, a mezők nevét mindig az adatokkal együtt kell tárolni; nem szabad támaszkodnia arra, hogy a konkrét pozíciókról rendelkezésre álló adatok rendelkezésre állnak.

Forrás
Leave a Reply
You must be logged in to post a answer.
A szerzőről
Ted