Konwertowanie tokenu (lub ciągu) na podany typ

TL; Wersja DR

Mam obiekt typuJToken (ale może być równieżstring) i muszę go przekonwertować na typ zawarty wtype zmienna:

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);

Powyższeresult powinien być obiektem DateTime o wartości podanej wdate_joined.

Pełna historia

Używam zarówno RestSharp, jak i Json.NET w projekcie Windows Phone i utknąłem podczas próby deserializacji odpowiedzi JSON z API REST.

W rzeczywistości staram się napisać ogólną metodę, która może łatwo odwzorować moją odpowiedź JSON na moje encje CLR, podobnie jak już można to zrobić za pomocą RestSharp. Jedynym problemem jest to, że domyślna implementacja RestSharp nie działa dla mnie i nie udaje się pomyślnie przeanalizować JSON, ponieważ odpowiedź nie zawsze zwraca wszystkie właściwości (nie zwracam pól, które sąnull z serwera REST).

Dlatego zdecydowałem się skorzystać z Json.NET Newtonsoft, ponieważ ma on znacznie mocniejszy silnik deserializujący Json. Niestety, nie obsługuje rozmytych nazw właściwości / pól, takich jak RestSharp (lub nie znalazłem żadnych), więc również nie mapuje poprawnie do moich elementów CLR, gdy używam czegoś podobnego do powiedzeniaJsonConvert.DeserializeObject<User>(response.Content).

Oto jak wygląda mój Json (przykład rzeczywiście):

{
    "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"
    }]
}

A oto przykład moich jednostek 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; }
}

To, czego chcę, to prosty sposób na przeanalizowanie powyższego JSON w podanych obiektach CLR. Rozejrzałem się po kodzie źródłowym RestSharp i widziałemJsonDeserializer kod i mogłem napisać ogólną metodę rozszerzeniaDeserializeResponse<T> naJObject które powinny zwrócić obiekt typuT. Zamierzonym zastosowaniem jest coś takiego:

var user = JObject.Parse(response.Content).DeserializeResponse<User>();

Powyższa metoda powinna analizować podaną odpowiedź Json na obiekt encji użytkownika. Oto prawdziwy fragment kodu tego, co robię wDeserializeResponse<User> metoda rozszerzenia (oparta na kodzie 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;
}

Zgaduję, że konwersja powinna być naprawdę prostą rzeczą, ponieważ jest banalnym zadaniem. Ale szukam od dłuższego czasu i nadal nie znalazłem sposobu, aby to zrobić za pomocą Json.NET (i szczerze mówiąc, dokumentacja jest trochę zrozumiała i brakuje jej przykładów).

Każda pomoc byłaby naprawdę doceniana.

questionAnswers(4)

yourAnswerToTheQuestion