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

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

我没有试图反序列化为强类型的.NET对象

我只需要一个普通的旧字典(Of String,String),或者一些等价的东西(哈希表,字典(OfString,Object),老式的StringDictionary——见鬼,一个二维字符串数组对我来说很有用。

我可以使用ASP.NET 3.5中可用的任何东西,也可以使用流行的Json.NET(我已经在使用它对客户端进行序列化)。

显然,这两个JSON库都没有这种开箱即用的能力——它们完全专注于通过强契约实现基于反射的反序列化。

有什么想法吗?

限制:

我不想实现我自己的JSON解析器尚无法使用ASP.NET 4.0希望远离旧的、不推荐使用的JSON ASP.NET类


当前回答

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

/// <summary>
/// Deserialize the given JSON string data (<paramref name="data"/>) into a
///   dictionary.
/// </summary>
/// <param name="data">JSON string.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(string data)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(data);

    return DeserializeData(values);
}

/// <summary>
/// Deserialize the given JSON object (<paramref name="data"/>) into a dictionary.
/// </summary>
/// <param name="data">JSON object.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(JObject data)
{
    var dict = data.ToObject<Dictionary<String, Object>>();

    return DeserializeData(dict);
}

/// <summary>
/// Deserialize any elements of the given data dictionary (<paramref name="data"/>) 
///   that are JSON object or JSON arrays into dictionaries or lists respectively.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(IDictionary<string, object> 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;
}

/// <summary>
/// Deserialize the given JSON array (<paramref name="data"/>) into a list.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized list.</returns>
private IList<Object> DeserializeData(JArray data)
{
    var list = data.ToObject<List<Object>>();

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

其他回答

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

/// <summary>
/// Deserialize the given JSON string data (<paramref name="data"/>) into a
///   dictionary.
/// </summary>
/// <param name="data">JSON string.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(string data)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(data);

    return DeserializeData(values);
}

/// <summary>
/// Deserialize the given JSON object (<paramref name="data"/>) into a dictionary.
/// </summary>
/// <param name="data">JSON object.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(JObject data)
{
    var dict = data.ToObject<Dictionary<String, Object>>();

    return DeserializeData(dict);
}

/// <summary>
/// Deserialize any elements of the given data dictionary (<paramref name="data"/>) 
///   that are JSON object or JSON arrays into dictionaries or lists respectively.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(IDictionary<string, object> 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;
}

/// <summary>
/// Deserialize the given JSON array (<paramref name="data"/>) into a list.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized list.</returns>
private IList<Object> DeserializeData(JArray data)
{
    var list = data.ToObject<List<Object>>();

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

尝试不使用任何外部JSON实现,所以我这样取消了序列化:

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

令人恼火的是,如果您想使用默认的模型绑定器,看起来您必须使用数字索引值,如表单POST。

请参阅本文的以下摘录http://msdn.microsoft.com/en-us/magazine/hh781022.aspx:

虽然这有点违反直觉,但JSON请求也有相同之处要求他们也必须遵守表单后命名语法。例如,上一个UnitPrice的JSON负载收集此数据的纯JSON数组语法为表示为:[ {“代码”:“USD”,“金额”:100.00},{“代码”:“EUR”,“金额”:73.64}]但是,默认值提供程序和模型绑定程序需要要表示为JSON表单帖子的数据:{“UnitPrice[0].Code”:“USD”,“单价[0]。金额”:100.00,“单价[1].代码”:“EUR”,“单价[1].金额”:73.64}复杂的对象收集场景可能是最复杂的场景之一开发人员遇到的问题广泛的场景,因为语法并不一定对所有开发人员都显而易见。然而,一旦你学习发布复杂集合的相对简单的语法,这些场景变得更容易处理。

我确实发现.NET有一种内置方式,可以通过3.5 System.Web.Extensions程序集中的System.Web.Script.Serialization.JavaScriptSerializer类型将JSON字符串转换为Dictionary<string,Object>。使用方法DeserializeObject(String)。

我在对静态.net页面方法进行内容类型为“application/json”的ajax发布(通过jquery)时偶然发现了这一点,并看到该方法(只有一个Object类型的参数)神奇地收到了这个字典。

对于那些在互联网上搜索并偶然发现这篇文章的人,我写了一篇关于如何使用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<dynamic>(json);
Console.WriteLine(table["id"]);
Console.WriteLine(table["value"]);