860 Stimmen

Wie kann ich JSON in ein einfaches Dictionary<string,string> in ASP.NET deserialisieren?

Ich habe eine einfache Schlüssel/Wert-Liste in JSON, die über POST an ASP.NET zurückgesendet wird. Beispiel:

{ "key1": "value1", "key2": "value2"}

ICH VERSUCHE NICHT, IN STARK GETYPTE .NET-OBJEKTE ZU DESERIALISIEREN

Ich brauche einfach einen einfachen alten Dictionary(Of String, String) oder ein Äquivalent (Hash-Tabelle, Dictionary(Of String, Object), StringDictionary der alten Schule - ein 2-D-Array von Strings würde für mich funktionieren.

Ich kann alles verwenden, was in ASP.NET 3.5 verfügbar ist, ebenso wie das beliebte Json.NET (das ich bereits für die Serialisierung verwende) zu den Kunden).

Offensichtlich keine dieser JSON-Bibliotheken haben diese Stirn schlagen offensichtliche Fähigkeit out of the box--sie sind völlig auf Reflexion-basierte Deserialisierung über starke Verträge konzentriert.

Irgendwelche Ideen?

Beschränkungen:

  1. Ich möchte nicht meinen eigenen JSON-Parser implementieren
  2. ASP.NET 4.0 kann noch nicht verwendet werden
  3. Ich würde es vorziehen, von der älteren, veralteten ASP.NET-Klasse für JSON wegzubleiben.

1 Stimmen

Zu: Einschränkung 3, JavaScriptSerizlizer wird in ASP.NET MVC verwendet und ist nicht mehr veraltet.

37 Stimmen

Es ist unglaublich, wie schwierig es war, einen einfachen Weg zu finden, um eine json-Zeichenfolge in etwas zu konvertieren, das ich leicht verwenden konnte, ohne durch viele verschiedene Stackoverflow zu blättern. Es ist so einfach in anderen Sprachen noch Java und C# scheint zu gehen aus dem Weg zu machen das Leben schwer.

42voto

PvH Punkte 421

Versucht, keine externe JSON-Implementierung zu verwenden, so dass ich wie folgt deserialisiert:

string json = "{\"id\":\"13\", \"value\": true}";

var serializer = new JavaScriptSerializer(); //using System.Web.Script.Serialization;

Dictionary<string, string> values = serializer.Deserialize<Dictionary<string, string>>(json);

7 Stimmen

Hinzufügen der Referenz System.Web.Extensions zur Verwendung von System.Web.Script

1 Stimmen

Diese Antwort gefällt mir am besten, weil sie einfach ist und die .NET System.Web.Script.Serialization . Es funktioniert einfach. Ich war sogar in der Lage, "ungültiges" JSON zu verwenden wie string json = "{'id':13, 'value': true}"; .

20voto

Falko Punkte 16072

Ich brauchte nur die Analyse einer verschachtelt Wörterbuch, wie

{
    "x": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}

donde JsonConvert.DeserializeObject hilft nicht. Ich habe den folgenden Ansatz gefunden:

var dict = JObject.Parse(json).SelectToken("x").ToObject<Dictionary<string, int>>();

El SelectToken können Sie bis zu dem gewünschten Feld vordringen. Sie können sogar einen Pfad angeben wie "x.y.z" um weiter in das JSON-Objekt hinabzusteigen.

0 Stimmen

JObject.Parse(json).ToObject<Dictionary<Guid, List<int>>>() hat in meinem Szenario funktioniert, danke

19voto

dexy Punkte 263

Wenn Sie nach einer leichtgewichtigen, keine hinzugefügten Verweise Art von Ansatz sind, vielleicht dieses Bit von Code, den ich gerade schrieb wird funktionieren (ich kann nicht 100% Robustheit garantieren, obwohl).

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

public Dictionary<string, object> ParseJSON(string json)
{
    int end;
    return ParseJSON(json, 0, out end);
}
private Dictionary<string, object> ParseJSON(string json, int start, out int end)
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    bool escbegin = false;
    bool escend = false;
    bool inquotes = false;
    string key = null;
    int cend;
    StringBuilder sb = new StringBuilder();
    Dictionary<string, object> child = null;
    List<object> arraylist = null;
    Regex regex = new Regex(@"\\u([0-9a-z]{4})", RegexOptions.IgnoreCase);
    int autoKey = 0;
    for (int i = start; i < json.Length; i++)
    {
        char c = json[i];
        if (c == '\\') escbegin = !escbegin;
        if (!escbegin)
        {
            if (c == '"')
            {
                inquotes = !inquotes;
                if (!inquotes && arraylist != null)
                {
                    arraylist.Add(DecodeString(regex, sb.ToString()));
                    sb.Length = 0;
                }
                continue;
            }
            if (!inquotes)
            {
                switch (c)
                {
                    case '{':
                        if (i != start)
                        {
                            child = ParseJSON(json, i, out cend);
                            if (arraylist != null) arraylist.Add(child);
                            else
                            {
                                dict.Add(key, child);
                                key = null;
                            }
                            i = cend;
                        }
                        continue;
                    case '}':
                        end = i;
                        if (key != null)
                        {
                            if (arraylist != null) dict.Add(key, arraylist);
                            else dict.Add(key, DecodeString(regex, sb.ToString()));
                        }
                        return dict;
                    case '[':
                        arraylist = new List<object>();
                        continue;
                    case ']':
                        if (key == null)
                        {
                            key = "array" + autoKey.ToString();
                            autoKey++;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                        dict.Add(key, arraylist);
                        arraylist = null;
                        key = null;
                        continue;
                    case ',':
                        if (arraylist == null && key != null)
                        {
                            dict.Add(key, DecodeString(regex, sb.ToString()));
                            key = null;
                            sb.Length = 0;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                       continue;
                    case ':':
                        key = DecodeString(regex, sb.ToString());
                        sb.Length = 0;
                        continue;
                }
            }
        }
        sb.Append(c);
        if (escend) escbegin = false;
        if (escbegin) escend = true;
        else escend = false;
    }
    end = json.Length - 1;
    return dict; //theoretically shouldn't ever get here
}
private string DecodeString(Regex regex, string str)
{
    return Regex.Unescape(regex.Replace(str, match => char.ConvertFromUtf32(Int32.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber))));
}

(Mir ist klar, dass dies gegen die OP-Beschränkung Nr. 1 verstößt, aber technisch gesehen haben nicht Sie es geschrieben, sondern ich)

4 Stimmen

Das ist die einzige Lösung, die für Silverlight und ohne Abhängigkeiten funktioniert! Silverlight hat keinen JavascriptSerializer oder Serializable. Und keine Abhängigkeit bedeutet kein Json.NET, RestSharp oder MiniJSON. Nur @DanCsharpster hat eine andere mögliche Lösung ausprobiert, aber leider hat sie bei mir nicht so funktioniert wie diese.

1 Stimmen

Was ist falsch daran, einen Verweis auf etwas Einfaches wie JSON.NET hinzuzufügen? Muss es denn so leichtgewichtig sein, dass man auf nichts verweisen kann? Ich sage nicht, dass Ihr Code nicht funktionieren wird, aber jedes Mal, wenn Sie Ihren eigenen Code entwickeln, laufen Sie natürlich Gefahr, dass Ihr Code nicht so robust ist, z. B. für Randfälle, oder so schnell wie eine getestete Bibliothek wie JSON.NET.

1 Stimmen

Es ist keine gute Idee, selbst zu rollen, wenn man eine gute Alternative hat. Ich kenne keine Situation, in der man sich que Leichtgewicht. Und ich hätte lieber einen weniger optimalen Code, der leicht zu lesen und zu ändern ist.

7voto

wdanxna Punkte 10294

Für alle, die versuchen, JSON in ein Wörterbuch zu konvertieren, nur um einen Wert daraus abzurufen. Es gibt ein einfacher Weg mit Newtonsoft.JSON

using Newtonsoft.Json.Linq
...

JObject o = JObject.Parse(@"{
  'CPU': 'Intel',
  'Drives': [
    'DVD read/writer',
    '500 gigabyte hard drive'
  ]
}");

string cpu = (string)o["CPU"];
// Intel

string firstDrive = (string)o["Drives"][0];
// DVD read/writer

IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList();
// DVD read/writer
// 500 gigabyte hard drive

6voto

Bryan Punkte 3559

Mark Rendle hat dies veröffentlicht als Kommentar Ich wollte es als Antwort posten, da es die einzige Lösung ist, die bisher funktioniert hat, um die Erfolgs- und Fehlercodes json-Ergebnisse aus der Google reCaptcha-Antwort zurückzugeben.

string jsonReponseString= wClient.DownloadString(requestUrl);    
IDictionary<string, object> dict = new JavaScriptSerializer().DeserializeObject(jsonReponseString) as IDictionary<string, object>;

Nochmals vielen Dank, Mark!

1 Stimmen

Der JavaScriptSerializer ist nahezu veraltet. Die Dokumentation sagt, dass wir JSON.NET verwenden sollten ( docs.microsoft.com/de-us/dotnet/api/ )

0 Stimmen

Auch gut für Legacy-Webforms-Anwendungen, bei denen Sie keine zusätzlichen Abhängigkeiten einbinden möchten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X