[c#] Konvertieren eines JToken (oder einer Zeichenfolge) in einen bestimmten Typ


1 Answers

System.Convert.ChangeType(jtoken.ToString(), targetType);

oder

JsonConvert.DeserializeObject(jtoken.ToString(), targetType);

--BEARBEITEN--

Uzair, Hier ist ein komplettes Beispiel, um Ihnen zu zeigen, dass sie funktionieren

string 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""
        }]
    }";

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

TL; DR-Version

Ich habe ein Objekt vom Typ JToken (kann aber auch eine string ) und muss es in einen Typ konvertieren, der in der Typvariablen enthalten ist:

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

Das obige result sollte ein DateTime-Objekt mit dem in date_joined angegebenen Wert date_joined .

Ganze Geschichte

Ich verwende sowohl RestSharp als auch Json.NET in einem Windows Phone-Projekt, und ich stehe fest, während ich versuche, JSON-Antworten von einer REST-API zu deserialisieren.

Was ich eigentlich erreichen möchte, ist eine generische Methode zu schreiben, die meine JSON-Antwort einfach in meine CLR-Entitäten mappen kann, so wie Sie es mit RestSharp bereits können. Das einzige Problem ist, dass die standardmäßige RestSharp-Implementierung für mich nicht funktioniert und das JSON nicht erfolgreich analysiert wird, da die Antwort nicht immer alle Eigenschaften zurückgibt (ich gebe keine Felder zurück, die vom REST-Server null sind).

Aus diesem Grund habe ich mich für Jerson.NET von Newtonsoft entschieden, da es eine wesentlich leistungsfähigere Engine zur Deserialisierung von Json bietet. Unglücklicherweise unterstützt es keine Fuzzy-Eigenschaften / Feldnamen wie RestSharp (oder ich habe keine gefunden), daher wird es auch nicht korrekt meinen CLR-Entitäten zugeordnet, wenn ich etwas wie zB JsonConvert.DeserializeObject<User>(response.Content) .

Hier ist, wie mein Json aussieht (ein Beispiel):

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

Und hier ist ein Beispiel für meine CLR-Entitäten:

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

Was ich will, ist eine einfache Möglichkeit, den obigen JSON in die gegebenen CLR-Objekte zu parsen. Ich habe mich im RestSharp-Quellcode umgeschaut und den JsonDeserializer Code gesehen, und ich konnte eine generische Erweiterungsmethode DeserializeResponse<T> auf JObject , die ein Objekt vom Typ T . Der Verwendungszweck ist etwa so:

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

Die obige Methode sollte die angegebene JSON-Antwort auf ein Benutzerentitätsobjekt analysieren. Hier ist ein tatsächliches Code-Snippet von dem, was ich in der DeserializeResponse<User> -Erweiterungsmethode mache (basierend auf RestSharp-Code):

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

Ich vermute, dass die Konvertierung eine wirklich einfache Sache sein sollte, da es eine triviale Aufgabe ist. Aber ich habe schon eine ganze Weile gesucht und habe immer noch keinen Weg gefunden, dies über Json.NET zu tun (und ehrlich gesagt, die Dokumentation ist irgendwie zu verstehen und es fehlen einige Beispiele).

Jede Hilfe würde wirklich geschätzt werden.




Ich konnte mit der Methode unterhalb für meine WebAPI konvertieren:

[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
}



Related