TL; DRバージョン
私はJToken
型のオブジェクトを持っていますが(string
にすることもできます)、それをtype
変数に含まれるTypeに変換する必要があります。
Type type = typeof(DateTime); /* can be any other Type like string, ulong etc */
var obj = jsonObject["date_joined"]; /* contains 2012-08-13T06:01:23Z+05:00 */
var result = Some_Way_To_Convert(type, obj);
上記のresult
は、date_joined
で指定された値を持つDateTimeオブジェクトでなければなりません。
フルストーリー
Windows PhoneプロジェクトでRestSharpとJson.NETの両方を使用していますが、REST APIからJSON応答をデシリアライズしようとしています。
私が実際に達成しようとしているのは、RestSharpで既にできるように、JSON応答をCLRエンティティに簡単にマッピングできる汎用メソッドを書くことです。唯一の問題は、デフォルトのRestSharp実装が機能しておらず、応答が常にすべてのプロパティを返すわけではないため(JSONからnull
のフィールドを返さないため)、JSONの解析に失敗することです。 RESTサーバー)。
それが、NewtonsoftのJson.NETを使用することに決めた理由です。NewtonsoftのJsonデシリアライズエンジンがはるかに強力だからです。残念ながら、RestSharpのようなファジープロパティ/フィールド名をサポートしていません(または見つかりません)。たとえば、JsonConvert.DeserializeObject<User>(response.Content)
などを使用すると、CLRエンティティに正しくマップされません。
これが私のJsonの外観です(実際の例)。
{
"id" : 77239923,
"username" : "UzEE",
"email" : "[email protected]",
"name" : "Uzair Sajid",
"Twitter_screen_name" : "UzEE",
"join_date" : "2012-08-13T05:30:23Z05+00",
"timezone" : 5.5,
"access_token" : {
"token" : "nkjanIUI8983nkSj)*#)(kjb@K",
"scope" : [ "read", "write", "bake pies" ],
"expires" : 57723
},
"friends" : [{
"id" : 2347484",
"name" : "Bruce Wayne"
},
{
"id" : 996236,
"name" : "Clark Kent"
}]
}
そして、これが私のCLRエンティティの例です:
class AccessToken
{
public string Token { get; set; }
public int Expires { get; set; }
public string[] Scope { get; set; }
public string Secret { get; set; } /* may not always be returned */
}
class User
{
public ulong Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string TwitterScreenName { get; set; }
public DateTime JoinDate { get; set; }
public float Timezone { get; set; }
public bool IsOnline { get; set; } /* another field that might be blank e.g. */
public AccessToken AccessToken { get; set; }
public List<User> Friends { get; set; }
}
私が欲しいのは、上記のJSONを指定されたCLRオブジェクトに解析する簡単な方法です。 RestSharpのソースコードを見て、JsonDeserializer
コードを見て、タイプのオブジェクトを返すJObject
にDeserializeResponse<T>
の汎用拡張メソッドを記述できました。 T
。使用目的は次のようなものです。
var user = JObject.Parse(response.Content).DeserializeResponse<User>();
上記のメソッドは、指定されたJson ResponseをUserエンティティオブジェクトに解析する必要があります。以下は、DeserializeResponse<User>
拡張メソッド(RestSharpコードに基づく)で私がやっていることの実際のコードスニペットです。
public static T DeserializeResponse<T>(this JObject obj) where T : new()
{
T result = new T();
var props = typeof(T).GetProperties().Where(p => p.CanWrite).ToList();
var objectDictionary = obj as IDictionary<string, JToken>;
foreach (var prop in props)
{
var name = prop.Name.GetNameVariants(CultureInfo.CurrentCulture).FirstOrDefault(n => objectDictionary.ContainsKey(n));
var value = name != null ? obj[name] : null;
if (value == null) continue;
var type = prop.PropertyType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = type.GetGenericArguments()[0];
}
// This is a problem. I need a way to convert JToken value into an object of Type type
prop.SetValue(result, ConvertValue(type, value), null);
}
return result;
}
簡単な作業なので、変換は本当に簡単なことだと思います。しかし、私はかなり長い間探していましたが、まだJson.NETを介してそれを行う方法を見つけていません(そして正直なところ、ドキュメントは理解するためのものであり、いくつかの例が欠けています)。
どんな助けも本当に感謝されます。
現在、ToObjectメソッドがあります。
var obj = jsonObject["date_joined"];
var result = obj.ToObject<DateTime>();
また、任意の複合型で動作し、JsonPropertyAttributeルールに従います
var result = obj.ToObject<MyClass>();
public class MyClass
{
[JsonProperty("date_field")]
public DateTime MyDate {get;set;}
}
System.Convert.ChangeType(jtoken.ToString(), targetType);
または
JsonConvert.DeserializeObject(jtoken.ToString(), targetType);
-EDIT-
Uzair、ここに彼らが働いていることを示すための完全な例があります
string json = @"{
""id"" : 77239923,
""username"" : ""UzEE"",
""email"" : ""[email protected]"",
""name"" : ""Uzair Sajid"",
""Twitter_screen_name"" : ""UzEE"",
""join_date"" : ""2012-08-13T05:30:23Z05+00"",
""timezone"" : 5.5,
""access_token"" : {
""token"" : ""nkjanIUI8983nkSj)*#)(kjb@K"",
""scope"" : [ ""read"", ""write"", ""bake pies"" ],
""expires"" : 57723
},
""friends"" : [{
""id"" : 2347484,
""name"" : ""Bruce Wayne""
},
{
""id"" : 996236,
""name"" : ""Clark Kent""
}]
}";
var obj = (JObject)JsonConvert.DeserializeObject(json);
Type type = typeof(int);
var i1 = System.Convert.ChangeType(obj["id"].ToString(), type);
var i2 = JsonConvert.DeserializeObject(obj["id"].ToString(), type);
var i2 = JsonConvert.DeserializeObject(obj["id"].ToString(), type);
最初の引数の周りに引用符がないため、解析例外をスローします(私は思う)。引用符を追加することで機能しました:
var i2 = JsonConvert.DeserializeObject("\"" + obj["id"].ToString() + "\"", type);
以下のメソッドを使用してWeb APIを変換できました。
[HttpPost]
public HttpResponseMessage Post(dynamic item) // Passing parameter as dynamic
{
JArray itemArray = item["Region"]; // You need to add JSON.NET library
JObject obj = itemArray[0] as JObject; // Converting from JArray to JObject
Region objRegion = obj.ToObject<Region>(); // Converting to Region object
}