I have sample Json and I need to serialize it into C# objects. I decided to leverage for this purpose Json.Net library. Also I need to have C# classes which will represent this Json. To create classes could be used Json C# class generator. There we have two options. "Create properties" and generated classes will look like:
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"));
}
}
}
and another option is "Generate pre-populated read-only fields" and classes will look like
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;
}
Both these generated classes rely on JObject and JsonClassHelper. But these classes could not be used with JsonSerializer like
var ro = jsonSerializer.Deserialize<RootObject>(reader);
We can create objects of these classes using JObject.Load method
var ro = new RootObject(Newtonsoft.Json.Linq.JObject.Load(reader));
Another way is to use online json2csharp converter and classes will look like
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 could deal with this class.
My question is what classes generator is preferable to use and what are benefits and drawbacks of using each type of generated classes?
Thank you for your suggestions.
I assume you want to deserialize json string to c# object. I usually create C# object by myself, and use JsonConvert to deserialize json string.
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; }
}
If you know what kind of objects you will be returning, then look at using the System.Runtime.Serialization.Json namespace in the 4.0 Framework. It's much easier to use than JSON.NET. In fact, it's probably the easiest alternative available.
After including references to this namespace (and a using statement), you need to mark up your classes with the [DataContract] attribute and each property with the [DataMember] attribute. Then, you can use a generic routine like this one:
/// <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;
}
}
}
And that is all there is to it.
I never use class generators. When there are few classes, I code them manually. When a lot of classes are needed for deserialization process, I prefer to use dynamic object, and use it as here which makes the code more readable.
Here is an example usage of 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);
}
来源:https://stackoverflow.com/questions/9229237/benefits-and-drawbacks-of-generated-c-sharp-classes-for-json-objects