JSON.NETテクニック
8417 ワード
1.シーケンス化に関するテクニック
プロパティによって一部のプロパティを無視する
時には、エンティティクラスの一部の属性をシーケンス化する必要があります.この場合、シーケンス化を必要としない属性を無視することを宣言します.この目標を達成するには、次の2つの方法があります.
まず、以下に示すように、
プログラムの実行:
シーケンス化が必要なクラスには多くの属性がありますが、その一部を使用する必要があります.上記の方法を使用すると煩雑になります(無視する必要がある属性が多すぎるため).この場合、
プログラムの実行:
ダイナミックシーケンス化オブジェクトのプロパティ
園友@夜色、花清浅の注意に感謝して、確かにこのようなシーンがあります:もっと多くの私たちが必要とするのは動的にどの属性をシーケンス化する必要があるかを決定することです.例えば、EmployeeBeanにとって:A方法は
オブジェクトをシーケンス化する際の循環参照異常の解決方法
オブジェクトをシーケンス化する場合、オブジェクトに集合属性があり、変更された集合のタイプがオブジェクト自体である場合、デフォルトのシーケンス化メソッドはループ参照の例外を報告します.シーケンス化が必要な場合は、次の属性を宣言するだけです.
2.逆シーケンス化に関するテクニック
2.1逆シーケンス化エンティティとして匿名タイプを使用
3.JSONの作成
参考&さらに読む
http://www.newtonsoft.com/json
プロパティによって一部のプロパティを無視する
時には、エンティティクラスの一部の属性をシーケンス化する必要があります.この場合、シーケンス化を必要としない属性を無視することを宣言します.この目標を達成するには、次の2つの方法があります.
まず、以下に示すように、
JsonIgnore
の特性修飾を用いてシーケンス化を必要としない属性を考慮することができる.public class EmployeeBean
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public decimal Salary { get; set; }
public string Phone { get; set; }
[JsonIgnore]
public DateTime HireDate { get; set; }
}
プログラムの実行:
var employeeBean = new EmployeeBean()
{
Id = Guid.NewGuid(),
Name = "gyzhao",
Email = "[email protected]",
Salary = 10000,
Phone = "13912390987",
HireDate = new DateTime(2012, 2, 1)
};
var jsonString = JsonConvert.SerializeObject(employeeBean, Formatting.Indented);
// :
//{
// "Id": "69a406ad-902c-45d3-8ba7-89a09779ed52",
// "Name": "gyzhao",
// "Email": "[email protected]",
// "Salary": 10000.0,
// "Phone": "13912390987"
//}
シーケンス化が必要なクラスには多くの属性がありますが、その一部を使用する必要があります.上記の方法を使用すると煩雑になります(無視する必要がある属性が多すぎるため).この場合、
DataContract
の特性を使用してシーケンス化されたクラスを修飾し、DataMember
の特性を使用してシーケンス化が必要な属性を修飾することを考慮することができます.このプロパティがない他のプロパティは自動的に無視されます.次のようになります.[DataContract]
public class EmployeeBean
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public decimal Salary { get; set; }
public string Phone { get; set; }
public DateTime? HireDate { get; set; }
}
プログラムの実行:
var employeeBean = new EmployeeBean()
{
Id = Guid.NewGuid(),
Name = "gyzhao",
Email = "[email protected]",
Salary = 10000,
Phone = "13912390987",
HireDate = new DateTime(2012, 2, 1)
};
var jsonString = JsonConvert.SerializeObject(employeeBean, Formatting.Indented);
// :
//{
// "Id": "69a406ad-902c-45d3-8ba7-89a09779ed52",
// "Name": "gyzhao",
// "Email": "[email protected]",
// "Salary": 10000.0
//}
DataContract
プロパティとDataMember
プロパティは、System.Runtime.Serialization
ネーミングスペースに従属します.ダイナミックシーケンス化オブジェクトのプロパティ
園友@夜色、花清浅の注意に感謝して、確かにこのようなシーンがあります:もっと多くの私たちが必要とするのは動的にどの属性をシーケンス化する必要があるかを決定することです.例えば、EmployeeBeanにとって:A方法は
Name
とId
の属性をシーケンス化する必要がありますが、B方法はEmail
とPhone
の属性をシーケンス化する必要があります.この場合、前の2つの使用特性の方式は需要の変化によく適応できず、JSONを検索する.NETのドキュメント(転送ゲート:Json.NET Documentation)、公式ドキュメントはこのAPIの例示的なプログラムを提供し、以下は改善された例である.var employeeBean = new EmployeeBean()
{
Id = Guid.NewGuid(),
Name = "gyzhao",
Email = "[email protected]",
Salary = 10000,
Phone = "13912390987",
HireDate = new DateTime(2015, 5, 4)
};
var perperties = new List<string>()
{
employeeBean.GetPropertyName(t => t.Email),
employeeBean.GetPropertyName(t => t.Phone)
};
var jsonString = JsonConvert.SerializeObject(employeeBean, Formatting.Indented, new JsonSerializerSettings()
{
ContractResolver = new JsonDynamicContractResolver(perperties)
});
//{
// "Email": "[email protected]",
// "Phone": "13912390987"
//}
Console.WriteLine(jsonString);
JsonDynamicContractResolver
クラスを定義する定義を次に示します.public class JsonDynamicContractResolver : DefaultContractResolver
{
private readonly List<string> _propertiesList;
public JsonDynamicContractResolver(IEnumerable<string> propertiesEnumerable)
{
if (propertiesEnumerable != null)
{
_propertiesList = propertiesEnumerable.ToList();
}
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
//
if (_propertiesList != null && _propertiesList.Any())
{
properties =
properties.Where(p => _propertiesList.Exists(pString => pString == p.PropertyName)).ToList();
}
return properties;
}
}
JsonDynamicContractResolver
コンストラクタ内の指定されたシーケンス化属性の集合を転送する際に、ここで拡張方法:GetPropertyName
を使用します.この方法は、Lambda
式を転送することによって、シーケンス化属性を必要とする文字列表現を取得します.ここでは、式ツリーによって実現されます.属性名を直接ハードコーディングする文字列に比べて,式ツリーを用いた動的取得は効率的に損なわれる(許容できる程度)が,設計上の柔軟性に置き換えられる.たとえば、プロパティ名を変更すると、コンパイラはタイプのセキュリティ保護を提供します.ハードコーディングでは、修正を忘れてしまうと異常が出てしまいますが、特にシステムにこのようなハードコーディング方式がたくさんあると、メンテナンスが悪夢になります.次に、拡張メソッドのコードを示します.public static class Extensions
{
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="func"></param>
/// <returns></returns>
public static string GetPropertyName<T>(this T obj, Expression<Func<T, object>> func)
{
var propertyName = string.Empty;
var expression = func.Body as UnaryExpression;
if (expression != null)
{
propertyName = ((MemberExpression) expression.Operand).Member.Name;
}
else
{
var memberExpression = func.Body as MemberExpression;
if (memberExpression != null)
{
propertyName = memberExpression.Member.Name;
}
else
{
var body = func.Body as ParameterExpression;
if (body != null)
{
propertyName = body.Type.Name;
}
}
}
return propertyName;
}
}
オブジェクトをシーケンス化する際の循環参照異常の解決方法
オブジェクトをシーケンス化する場合、オブジェクトに集合属性があり、変更された集合のタイプがオブジェクト自体である場合、デフォルトのシーケンス化メソッドはループ参照の例外を報告します.シーケンス化が必要な場合は、次の属性を宣言するだけです.
JsonConvert.SerializeObject(result,new JsonSerializerSettings{ReferenceLoopHandling=ReferenceLoopHandling.Serialize})
2.逆シーケンス化に関するテクニック
2.1逆シーケンス化エンティティとして匿名タイプを使用
var jsonString = @"{
'Id': '69a406ad-902c-45d3-8ba7-89a09779ed52',
'Name': 'gyzhao',
'Salary': 10000.0,
'HireDate': '2012-02-01T00:00:00'
}";
var employee = new
{
Name = default(string),
Salary = default(decimal),
HireDate = default(DateTime),
Id = default(Guid)
};
var employeeBean = JsonConvert.DeserializeAnonymousType(jsonString, employee);
3.JSONの作成
// JSON
var array = new JArray();
var text = new JValue("Manual text");
var date = new JValue(DateTime.Now);
array.Add(text);
array.Add(date);
Console.WriteLine(array.ToString());
//
var rss =
new JObject(
new JProperty("channel", new JObject(
new JProperty("title", "James Nexton-king"),
new JProperty("link", "http://james.newtonking.com"),
new JProperty("description", "James Newton-Kin's blog."),
new JProperty("item", "BB"))));
Console.WriteLine(rss.ToString());
// JSON
JObject o = JObject.FromObject(new
{
channel = new
{
title = "James Newton-king",
link = "http://james.netwoing.com",
item = new List<string>()
{
"A",
"B",
"C",
"D",
"E"
}
}
});
Console.WriteLine(o.ToString());
参考&さらに読む
http://www.newtonsoft.com/json