当前位置:  开发笔记 > 编程语言 > 正文

如何在ASP.NET中将JSON反序列化为简单的Dictionary <string,string>?

如何解决《如何在ASP.NET中将JSON反序列化为简单的Dictionary<string,string>?》经验,为你挑选了10个好方法。

我在JSON中有一个简单的键/值列表,通过POST发送回ASP.NET.例:

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

我并没有想要进入强大的.NET对象

我只需要一个普通的旧的Dictionary(Of String,String),或者一些等价的(hash table,Dictionary(Of String,Object),old-school StringDictionary - hell,一个2-D字符串数组对我有用.

我可以使用ASP.NET 3.5中的任何可用内容,以及流行的Json.NET(我已经将其用于序列化客户端).

显然,这些JSON库都没有开箱即用的明显功能 - 它们完全专注于通过强大的合同进行基于反射的反序列化.

有任何想法吗?

限制:

    我不想实现自己的JSON解析器

    无法使用ASP.NET 4.0

    宁愿远离旧的,已弃用的JSON ASP.NET类

James Newton.. 843

Json.NET这样做......

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject>(json);

更多示例:使用Json.NET序列化集合



1> James Newton..:

Json.NET这样做......

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject>(json);

更多示例:使用Json.NET序列化集合


@Highmastdon不,不.我发现反序列化为字典的最好方法是使用`dynamic`作为值的类型:`JsonConvert.DeserializeObject >(json);`
如果你在json中使用一组键值对,则不起作用`[{key:"a",value:"1"},{key:"b",value:"2"}]`你有做这样的事情:`var dict = JsonConvert.DeserializeObject >>(json);`
当值是整数时,这是否也有效.它们会自动转换为"字符串"吗?
如果值是嵌套对象,也不起作用,因为json.net将它们创建为JObject

2> 小智..:

我没有发现.NET有一个内置的方式投JSON字符串成Dictionary通过System.Web.Script.Serialization.JavaScriptSerializer在3.5型System.Web.Extensions装配.使用该方法DeserializeObject(String).

当我将一个内容类型为'application/json'的ajax帖子(通过jquery)发送到一个静态.net页面方法时,我偶然发现了这一点,并看到该方法(具有单一参数类型Object)神奇地接收了这个词典.


快速代码示例:`var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();`后跟`Dictionary dict =(Dictionary )jsSerializer.DeserializeObject(jsonString);`
在简单的情况下,Nate Cook的例子的优点是避免使用外部DLL.我从一个只能依赖.Net框架的独立控制台访问API.
但内置的javascriptserializer比json.net更笨,这个解决方案更好.例如,javascriptseralizer将返回空值而不是空字符串,并且对于可空属性完全不起作用,依此类推.

3> JP Richardso..:

对于那些搜索互联网并绊倒这篇文章的人,我写了一篇关于如何使用JavaScriptSerializer类的博客文章.

阅读更多... http://procbits.com/2011/04/21/quick-json-serializationdeserialization-in-c/

这是一个例子:

var json = "{\"id\":\"13\", \"value\": true}";
var jss = new JavaScriptSerializer();
var table = jss.Deserialize(json);
Console.WriteLine(table["id"]);
Console.WriteLine(table["value"]);



4> 小智..:

试图不使用任何外部JSON实现,所以我反序列化如下:

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

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

Dictionary values = serializer.Deserialize>(json);


添加引用System.Web.Extensions以使用System.Web.Script

5> Dasun..:

我有同样的问题,所以我写了这个我自己.此解决方案与其他答案不同,因为它可以反序列化为多个级别.

只需将JSON字符串发送到deserializeToDictionary函数,它将返回非强类型Dictionary对象.

旧代码

private Dictionary deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject>(jo);
    var values2 = new Dictionary();
    foreach (KeyValuePair d in values)
    {
        // if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        if (d.Value is JObject)
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

例如:这将返回DictionaryFacebook JSON响应的对象.

测试

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",  hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary values = deserializeToDictionary(responsestring);
}

注意:故乡进一步将一个Dictionary 物体变成一个物体.

更新

如果JSON字符串上没有数组,那么我的旧答案会很有效.List如果元素是数组,则进一步反序列化为if.

只需将一个JSON字符串发送到deserializeToDictionaryOrList函数,它将返回非强类型Dictionary对象或List.

private static object deserializeToDictionaryOrList(string jo,bool isArray=false)
{
    if (!isArray)
    {
        isArray = jo.Substring(0, 1) == "[";
    }
    if (!isArray)
    {
        var values = JsonConvert.DeserializeObject>(jo);
        var values2 = new Dictionary();
        foreach (KeyValuePair d in values)
        {
            if (d.Value is JObject)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
            }
            else if (d.Value is JArray)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString(), true));
            }
            else
            {
                values2.Add(d.Key, d.Value);
            }
        }
        return values2;
    }else
    {
        var values = JsonConvert.DeserializeObject>(jo);
        var values2 = new List();
        foreach (var d in values)
        {
            if (d is JObject)
            {
                values2.Add(deserializeToDictionary(d.ToString()));
            }
            else if (d is JArray)
            {
                values2.Add(deserializeToDictionary(d.ToString(), true));
            }
            else
            {
                values2.Add(d);
            }
        }
        return values2;
    }
}



6> dexy..:

如果您正在使用轻量级,无添加引用的方法,那么我刚写的这些代码可能会起作用(尽管我不能100%保证稳健性).

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

public Dictionary ParseJSON(string json)
{
    int end;
    return ParseJSON(json, 0, out end);
}
private Dictionary ParseJSON(string json, int start, out int end)
{
    Dictionary dict = new Dictionary();
    bool escbegin = false;
    bool escend = false;
    bool inquotes = false;
    string key = null;
    int cend;
    StringBuilder sb = new StringBuilder();
    Dictionary child = null;
    List 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();
                        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))));
}


[我意识到这违反了OP限制#1,但从技术上讲,你没有写它,我做了]


这是唯一适用于Silverlight并且没有依赖性的答案!Silverlight没有JavascriptSerializer或Serializable.没有依赖意味着没有Json.NET,RestSharp或MiniJSON.只有@DanCsharpster尝试了另一种可能的解决方案,但不幸的是,这对我来说不像这样.
我最初写了那段代码,因为我别无选择.考虑诸如Silverlight或Office产品的各种类型的提供程序之类的东西,其中向项目添加外部引用要么是极其成问题,要么是不可能的.

7> Falko..:

我只需要解析一个嵌套字典,比如

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

哪里JsonConvert.DeserializeObject没有帮助.我找到了以下方法:

var dict = JObject.Parse(json).SelectToken("x").ToObject>();

SelectToken让你挖掘到所需的字段.您甚至可以指定一个类似于"x.y.z"进一步向下进入JSON对象的路径.



8> Bryan..:

马克·雷德尔(Mark Rendle)将此作为评论发表,我想将其作为答案发表,因为它是迄今为止返回成功的唯一解决方案,并且是来自Google reCaptcha响应的错误代码json结果。

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

再次感谢,马克!



9> richardtalle..:

编辑:这是有效的,但使用Json.NET接受的答案要简单得多.离开这个以防万一有人需要BCL专用代码.

开箱即用的.NET框架不支持它.一个明显的疏忽 - 不是每个人都需要反序列化为具有命名属性的对象.所以我最终滚动自己:

 Public Class StringStringDictionary
    Implements ISerializable
    Public dict As System.Collections.Generic.Dictionary(Of String, String)
    Public Sub New()
        dict = New System.Collections.Generic.Dictionary(Of String, String)
    End Sub
    Protected Sub New(info As SerializationInfo, _
          context As StreamingContext)
        dict = New System.Collections.Generic.Dictionary(Of String, String)
        For Each entry As SerializationEntry In info
            dict.Add(entry.Name, DirectCast(entry.Value, String))
        Next
    End Sub
    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData
        For Each key As String in dict.Keys
            info.AddValue(key, dict.Item(key))
        Next
    End Sub
End Class

叫:

string MyJsonString = "{ \"key1\": \"value1\", \"key2\": \"value2\"}";
System.Runtime.Serialization.Json.DataContractJsonSerializer dcjs = new
  System.Runtime.Serialization.Json.DataContractJsonSerializer(
    typeof(StringStringDictionary));
System.IO.MemoryStream ms = new
  System.IO.MemoryStream(Encoding.UTF8.GetBytes(MyJsonString));
StringStringDictionary myfields = (StringStringDictionary)dcjs.ReadObject(ms);
Response.Write("Value of key2: " + myfields.dict["key2"]);

对不起C#和VB.NET的混合......


[TestMethod] public void TestSimpleObject(){const string json = @"{""Name"":""Bob"",""Age"":42}"; var dict = new JavaScriptSerializer().DeserializeObject(json)as IDictionary ; Assert.IsNotNull(字典); Assert.IsTrue(dict.ContainsKey( "名称")); Assert.AreEqual("Bob",dict ["Name"]); Assert.IsTrue(dict.ContainsKey( "时代")); Assert.AreEqual(42,dict ["Age"]); }

10> Jordan..:

我添加了jSnake04和Dasun在此提交的代码.我添加了代码来创建JArray实例中的对象列表.它具有双向递归,但由于它在固定的有限树模型上运行,因此除非数据量很大,否则不存在堆栈溢出的风险.

/// 
/// Deserialize the given JSON string data () into a
///   dictionary.
/// 
/// JSON string.
/// Deserialized dictionary.
private IDictionary DeserializeData(string data)
{
    var values = JsonConvert.DeserializeObject>(data);

    return DeserializeData(values);
}

/// 
/// Deserialize the given JSON object () into a dictionary.
/// 
/// JSON object.
/// Deserialized dictionary.
private IDictionary DeserializeData(JObject data)
{
    var dict = data.ToObject>();

    return DeserializeData(dict);
}

/// 
/// Deserialize any elements of the given data dictionary () 
///   that are JSON object or JSON arrays into dictionaries or lists respectively.
/// 
/// Data dictionary.
/// Deserialized dictionary.
private IDictionary DeserializeData(IDictionary data)
{
    foreach (var key in data.Keys.ToArray()) 
    {
        var value = data[key];

        if (value is JObject)
            data[key] = DeserializeData(value as JObject);

        if (value is JArray)
            data[key] = DeserializeData(value as JArray);
    }

    return data;
}

/// 
/// Deserialize the given JSON array () into a list.
/// 
/// Data dictionary.
/// Deserialized list.
private IList DeserializeData(JArray data)
{
    var list = data.ToObject>();

    for (int i = 0; i < list.Count; i++)
    {
        var value = list[i];

        if (value is JObject)
            list[i] = DeserializeData(value as JObject);

        if (value is JArray)
            list[i] = DeserializeData(value as JArray);
    }

    return list;
}

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有