TL;DR バージョン
タイプのオブジェクトがありますJToken
(ただし、 の場合もあります)。それを変数string
に含まれるタイプに変換する必要があります。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
は、 で指定された値を持つ DateTime オブジェクトである必要がありますdate_joined
。
フルストーリー
Windows Phone プロジェクトで RestSharp と Json.NET の両方を使用していますが、REST API からの JSON 応答を逆シリアル化しようとしてスタックしています。
私が実際に達成しようとしているのは、RestSharp で既にできるように、JSON 応答を CLR エンティティに簡単にマップできる汎用メソッドを作成することです。null
唯一の問題は、デフォルトの RestSharp 実装が機能せず、応答がすべてのプロパティを返すとは限らない ( REST サーバーからのフィールドを返さない) ため、JSON を正常に解析できないことです。
そのため、はるかに強力な Json デシリアライズ エンジンを備えている Newtonsoft の Json.NET を使用することにしました。残念ながら、RestSharp のようなあいまいなプロパティ/フィールド名をサポートしていない (または見つからなかった) ため、 say のようなものを使用すると、CLR エンティティにも正しくマップされませんJsonConvert.DeserializeObject<User>(response.Content)
。
これが私のJsonの外観です(実際の例):
{
"id" : 77239923,
"username" : "UzEE",
"email" : "uzee@email.net",
"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
書くことができました。使用目的は次のようなものです。DeserializeResponse<T>
JObject
T
var user = JObject.Parse(response.Content).DeserializeResponse<User>();
上記のメソッドは、指定された Json レスポンスを 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 を介してそれを行う方法をまだ見つけていません (正直に言うと、ドキュメントは理解するのにちょっと手間がかかり、いくつかの例が欠けています)。
どんな助けでも本当に感謝します。