Преимущества и недостатки сгенерированных классов C # для объектов Json - PullRequest
4 голосов
/ 10 февраля 2012

У меня есть образец Json, и мне нужно сериализовать его в объекты C #.Я решил использовать для этой цели библиотеку Json.Net .Также мне нужно иметь классы C #, которые будут представлять этот Json.Для создания классов может быть использован генератор классов Json C # .Там у нас есть два варианта.«Создать свойства» и сгенерированные классы будут выглядеть так:

public class Address
{
    private JObject __jobject;
    public Address(JObject obj)
    {
        this.__jobject = obj;
    }
    public string street_address
    {
        get
        {
            return JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(__jobject, "street_address"));
        }
    }
    public string city
    {
        get
        {
            return JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(__jobject, "city"));
        }
    }
    public string state_province
    {
        get
        {
            return JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(__jobject, "state_province"));
        }
    }
    public string zip_postal_code
    {
        get
        {
            return JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(__jobject, "zip_postal_code"));
        }
    }
}

, а другой параметр - «Создать предварительно заполненные поля только для чтения», а классы будут выглядеть как

public class Address
{

    public Address(JObject obj)
    {
       this.street_address = JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(obj, "street_address"));
       this.city = JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(obj, "city"));
       this.state_province = JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(obj, "state_province"));
       this.zip_postal_code = JsonClassHelper.ReadString(JsonClassHelper.GetJToken<JValue>(obj, "zip_postal_code"));
    }

    public readonly string street_address;
    public readonly string city;
    public readonly string state_province;
    public readonly string zip_postal_code;
}

Оба этисгенерированные классы полагаются на JObject и JsonClassHelper.Но эти классы нельзя использовать с JsonSerializer, например

var ro = jsonSerializer.Deserialize<RootObject>(reader);

. Мы можем создавать объекты этих классов с помощью метода JObject.Load

var ro = new RootObject(Newtonsoft.Json.Linq.JObject.Load(reader));

Другой способ - использовать онлайн json2csharp конвертер и классы будут выглядеть так:

public class Address
{
    public string street_address { get; set; }
    public string city { get; set; }
    public string state_province { get; set; }
    public string zip_postal_code { get; set; }
}

JsonSerializer может справиться с этим классом.

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

Ответы [ 3 ]

3 голосов
/ 10 февраля 2012

Если вы знаете, какие объекты вы будете возвращать, посмотрите на использование пространства имен System.Runtime.Serialization.Json в 4.0 Framework. Это намного проще в использовании, чем JSON.NET. На самом деле, это, вероятно, самая простая альтернатива из доступных.

После включения ссылок на это пространство имен (и с использованием оператора ) вам нужно пометить свои классы атрибутом [DataContract] , а каждое свойство - [ DataMember] атрибут. Затем вы можете использовать общую процедуру, подобную этой:

/// <summary>
/// 
/// Generic helper class to convert JSON text to in-memory objects
/// </summary>
/// <typeparam name="T">Type of class that the text represents</typeparam>
public class JSONHandler<T> where T : class, new()
{
    /// <summary>
    /// Convert a JSON string to an in-memory object of class T.
    /// The class T must be instantiable and not static.
    /// </summary>
    /// <param name="JSONString">JSON string describing the top level object</param>
    /// <returns>Object of class T (and any dependent objects)</returns>
    public T TextToJSON(string JSONString)
    {
        //check that we aren't passing in empty text
        if (String.IsNullOrEmpty(JSONString))
        {
            return null;
        }
        else
        {
            //create a new object
            T JSONObject = new T();
            //and create a new serializer for it
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            //create a memor stream around the text
            System.IO.MemoryStream ms = new System.IO.MemoryStream(Encoding.Unicode.GetBytes(JSONString));
            //do the conversion
            JSONObject = (T)ser.ReadObject(ms);
            //tidy up after ourselves
            ms.Close();
            //and we're done!
            return JSONObject;
        }
    }       
}

И это все, что нужно сделать.

3 голосов
/ 10 февраля 2012

Полагаю, вы хотите десериализовать строку json в объект c #. Обычно я сам создаю объект C # и использую JsonConvert для десериализации строки json.

class Program {
        static void Main(string[] args)
        {
                string json = @"
                {
                        ""street_address"":""My street address"",
                        ""city"":""My City"",
                        ""state_province"":""My State Province"",
                        ""zip_postal_code"":""My Zip Postal Code"",
                }";

                Address address = JsonConvert.DeserializeObject<Address>(json);
                Console.WriteLine("Street address: {0}", address.StreetAddress);
                Console.WriteLine("City: {0}", address.City);
                Console.WriteLine("State province: {0}", address.StateProvince);
                Console.WriteLine("Zip postal code: {0}", address.ZipPostalCode);
        }
}

public class Address {
        [JsonProperty("street_address")]
        public string StreetAddress { get; set; }

        [JsonProperty("city")]
        public string City { get; set; }

        [JsonProperty("state_province")]
        public string StateProvince { get; set; }

        [JsonProperty("zip_postal_code")]
        public string ZipPostalCode { get; set; }
}
2 голосов
/ 10 февраля 2012

Я никогда не использую генераторы классов. Когда есть несколько классов, я кодирую их вручную. Когда для процесса десериализации требуется много классов, я предпочитаю использовать объект dynamic и использовать его как здесь , что делает код более читабельным.

Вот пример использования dynamic json

string json = @"{Users:[{Name:'name1',Id:1},{Name:'name2',Id:2}]}";
dynamic obj = JsonUtils.JsonObject.GetDynamicJsonObject(json);
foreach (var user in obj.Users)
{
    Console.WriteLine("{0} {1}", user.Name, user.Id);
}
...