我在JSON中有一个简单的键/值列表通过POST发送回ASP.NET . 例:
{ "key1": "value1", "key2": "value2"}
I AM NOT TRYING TO DESERIALIZE INTO STRONGLY-TYPED .NET OBJECTS
我只需要一个普通的旧的 Dictionary(Of String, String) ,或者一些等价的(哈希表,字典(Of String,Object),旧式的StringDictionary - 地狱,一个二维的字符串数组对我有用 .
我可以使用ASP.NET 3.5中的任何可用内容,以及流行的Json.NET(我已经用于序列化 to 客户端) .
显然,这些JSON库都没有开箱即用的前瞻性功能 - 它们完全专注于通过强大 Contract 进行基于反射的反序列化 .
有任何想法吗?
限制:
-
我不想实现自己的JSON解析器
-
尚未使用ASP.NET 4.0
-
宁愿远离旧的,已弃用的JSON ASP.NET类
19 回答
我发现.NET有一种内置的方法可以通过3.5
System.Web.Extensions
程序集中的System.Web.Script.Serialization.JavaScriptSerializer
类型将JSON字符串转换为Dictionary<String, Object>
. 使用方法DeserializeObject(String)
.当我将一个内容类型为'application/json'的ajax帖子(通过jquery)发送到一个静态.net页面方法时,我偶然发现了这一点,并看到该方法(具有
Object
类型的单个参数)神奇地接收了这个词典 .我建议使用
System.Runtime.Serialization.Json
,它是.NET 4.5的一部分 .然后像这样使用它:
似乎所有这些答案都假设你可以从一个更大的对象中得到那个小字符串...对于那些希望简单地在映射中的某个地方用这样的字典去实现一个大对象的人,以及谁正在使用
System.Runtime.Serialization.Json
DataContract系统,这是一个解决方案:An answer on gis.stackexchange.com有this interesting link . 我必须使用archive.org恢复它,但它提供了一个非常完美的解决方案:一个自定义
IDataContractSurrogate
类,您可以在其中实现您自己的类型 . 我能够轻松扩展它 .不过,我做了一些改变 . 由于原始资源不再可用,我将在此发布整个课程:
要向类添加新的受支持类型,只需添加类,为其提供正确的构造函数和函数(例如,查看
SurrogateDictionary
),确保它继承JsonSurrogateObject
,并将其类型映射添加到KnownTypes
字典 . 包含的SurrogateDictionary可以作为任何Dictionary<String,T>
类型的基础,其中T是任何正确反序列化的类型 .调用它非常简单:
请注意,由于某种原因,使用包含空格的键字符串会出现问题 . 他们根本没有出现在最终名单中 . 可能只是因为它只是针对json规范而且我打电话的api执行得很差,请注意;我不知道 . 无论如何,我通过正则表达式解决了这个问题 - 用原始json数据中的下划线替换它们并在反序列化后修复字典 .
我在JSON中添加了对空值的检查到另一个答案
我有同样的问题,所以我写了这个我自己 . 此解决方案与其他答案不同,因为它可以反序列化为多个级别 .
只需将json字符串发送到 deserializeToDictionary 函数,它将返回非强类型的
Dictionary<string, object>
对象 .例如:这将返回Facebook JSON响应的
Dictionary<string, object>
对象 .注意:hometown进一步反序列化为
Dictionary<string, object>
对象 .游戏有点晚了,但没有上述解决方案使我指向纯粹简单的.NET,没有json.net解决方案 . 所以在这里,结果非常简单 . 下面是一个完整的运行示例,说明如何使用标准.NET Json序列化,该示例在根对象和子对象中都有字典 .
黄金子弹是这只猫,将设置解析为序列化器的第二个参数:
完整代码如下:
试图不使用任何外部JSON实现,所以我反序列化如下:
我刚刚在RestSharp中实现了这一点 . This post对我有帮助 .
除了链接中的代码,这是我的代码 . 当我做这样的事情时,我现在得到
Dictionary
的结果:请注意您期望的那种JSON - 在我的例子中,我正在检索具有多个属性的单个对象 . 在附加链接中,作者正在检索列表 .
Mark Rendle发布了这个as a comment,我想发布它作为答案,因为它是目前为止唯一能够返回成功的解决方案,以及来自Google reCaptcha响应的错误代码json结果 .
马克,再次感谢!
我的方法直接反序列化为IDictionary,中间没有JObject或ExpandObject . 代码使用转换器,它基本上是从JSON.NET源代码中的ExpandoObjectConverter类复制的,但是使用IDictionary而不是ExpandoObject .
Usage:
Code:
我添加了代码来创建
JArray
实例中的对象列表 . 它有双向递归但是它在固定的有限树模型上运行,除非数据量很大,否则不存在堆栈溢出的风险 .对于那些搜索互联网并绊倒这篇文章的人,我写了一篇关于如何使用JavaScriptSerializer类的博客文章 .
阅读更多... http://procbits.com/2011/04/21/quick-json-serializationdeserialization-in-c/
这是一个例子:
Json.NET这样做......
更多例子:Serializing Collections with Json.NET
根据评论above试试
JsonConvert.DeserializeObject<Dictionary<string,dynamic>>(json)
似乎甚至可以用于复杂的对象和列表 .
我只需要解析一个嵌套字典,比如
哪里
JsonConvert.DeserializeObject
没有帮助 . 我找到了以下方法:SelectToken
可让您深入到所需的字段 . 您甚至可以指定像"x.y.z"
这样的路径,以进一步向下进入JSON对象 .令人讨厌的是,如果你想使用默认的模型 Binders ,看起来你必须使用数字索引值,如表单POST .
请参阅以下文章http://msdn.microsoft.com/en-us/magazine/hh781022.aspx的摘录:
“UnitPrice [1] .Code”:“EUR”,
“UnitPrice [1] .Amount”:73.64
}
复杂的对象集合场景可能是开发人员遇到的最广泛问题的场景之一,因为语法并不一定对所有开发人员都很明显 . 但是,一旦您了解了发布复杂集合的相对简单的语法,这些场景就变得更容易处理 .
Edit: 这有效,但使用Json.NET接受的答案要简单得多 . 留下这个以防万一有人需要BCL专用代码 .
开箱即用的.NET框架不支持它 . 一个明显的疏忽 - 不是每个人都需要反序列化为具有命名属性的对象 . 所以我最后自己动手:
叫:
对不起C#和VB.NET的混合......
我有同样的问题,所以我写了这个我自己 . 此解决方案与其他答案不同,因为它可以反序列化为多个级别 .
只需将JSON字符串发送到 deserializeToDictionary 函数,它将返回非强类型的
Dictionary<string, object>
对象 .Old code
例如:这将返回Facebook JSON响应的
Dictionary<string, object>
对象 .Test
Update
如果JSON字符串上没有数组,那么我的旧答案很有效 . 如果元素是数组,则进一步反序列化为
List<object>
.只需将一个JSON字符串发送到 deserializeToDictionaryOrList 函数,它将返回非强类型的
Dictionary<string, object>
对象或List<object>
.如果您正在使用轻量级,无添加引用的方法,那么我刚写的这些代码可能会起作用(尽管我不能100%保证稳健性) .
[我意识到这违反了OP限制#1,但从技术上讲,你没有写它,我做了]
你可以用Tiny-JSON