Преобразование JToken (или строки) в данный тип

TL;DR Version

У меня есть объект типа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.

Full Story

Я использую как RestSharp, так и Json.NET в проекте Windows Phone, и я застрял, пытаясь десериализовать ответы JSON от REST API.

То, что я на самом деле пытаюсь выполнить, - это написать универсальный метод, который может легко отобразить мой ответ JSON в мои объекты CLR, так же, как вы уже можете делать с RestSharp. Единственная проблема заключается в том, что реализация RestSharp по умолчанию не работает для меня, и он не может успешно проанализировать JSON, поскольку ответ не всегда возвращает все свойства (я не возвращаю поля, которые являютсяnull с сервера REST).

Вот почему я решил использовать Json.NET от Newtonsoft, поскольку он имеет гораздо более мощный механизм десериализации Json. К сожалению, он не поддерживает нечеткие имена свойств / полей, такие как RestSharp (или я их не нашел), поэтому он также не отображается правильно на мои объекты CLR, когда я использую что-то вроде sayJsonConvert.DeserializeObject<User>(response.Content).

Вот как выглядит мой 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 код и я смог написать общий метод расширения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 (и, честно говоря, документация вроде бы понятна и не содержит некоторых примеров).

Любая помощь будет принята с благодарностью.

Ответы на вопрос(4)

Ваш ответ на вопрос