ric*_*ent 642 json asp.net-ajax asp.net-3.5 json.net
我在JSON中有一个简单的键/值列表,通过POST发送回ASP.NET.例:
{ "key1": "value1", "key2": "value2"}
Run Code Online (Sandbox Code Playgroud)
我并没有想要进入强大的.NET对象
我只需要一个普通的旧的Dictionary(Of String,String),或者一些等价的(hash table,Dictionary(Of String,Object),old-school StringDictionary - hell,一个2-D字符串数组对我有用.
我可以使用ASP.NET 3.5中的任何可用内容,以及流行的Json.NET(我已经将其用于序列化到客户端).
显然,这些JSON库都没有开箱即用的明显功能 - 它们完全专注于通过强大的合同进行基于反射的反序列化.
有任何想法吗?
限制:
Jam*_*ing 843
Json.NET这样做......
string json = @"{""key1"":""value1"",""key2"":""value2""}";
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Run Code Online (Sandbox Code Playgroud)
更多示例:使用Json.NET序列化集合
小智 97
我没有发现.NET有一个内置的方式投JSON字符串成Dictionary<String, Object>通过System.Web.Script.Serialization.JavaScriptSerializer在3.5型System.Web.Extensions装配.使用该方法DeserializeObject(String).
当我将一个内容类型为'application/json'的ajax帖子(通过jquery)发送到一个静态.net页面方法时,我偶然发现了这一点,并看到该方法(具有单一参数类型Object)神奇地接收了这个词典.
JP *_*son 52
对于那些搜索互联网并绊倒这篇文章的人,我写了一篇关于如何使用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"]);
Run Code Online (Sandbox Code Playgroud)
小智 40
试图不使用任何外部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);
Run Code Online (Sandbox Code Playgroud)
Das*_*sun 36
我有同样的问题,所以我写了这个我自己.此解决方案与其他答案不同,因为它可以反序列化为多个级别.
只需将JSON字符串发送到deserializeToDictionary函数,它将返回非强类型Dictionary<string, object>对象.
旧代码
private Dictionary<string, object> deserializeToDictionary(string jo)
{
var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
var values2 = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> 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;
}
Run Code Online (Sandbox Code Playgroud)
例如:这将返回Dictionary<string, object>Facebook 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<string, object> values = deserializeToDictionary(responsestring);
}
Run Code Online (Sandbox Code Playgroud)
注意:故乡进一步将一个
Dictionary<string, object>物体变成一个物体.
更新
如果JSON字符串上没有数组,那么我的旧答案会很有效.List<object>如果元素是数组,则进一步反序列化为if.
只需将一个JSON字符串发送到deserializeToDictionaryOrList函数,它将返回非强类型Dictionary<string, object>对象或List<object>.
private static object deserializeToDictionaryOrList(string jo,bool isArray=false)
{
if (!isArray)
{
isArray = jo.Substring(0, 1) == "[";
}
if (!isArray)
{
var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
var values2 = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> 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<List<object>>(jo);
var values2 = new List<object>();
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;
}
}
Run Code Online (Sandbox Code Playgroud)
hal*_*ldo 28
现在可以使用System.Text.Json内置于.NET Core 3.0 中的它来完成。现在可以在不使用第三方库的情况下反序列化 JSON 。
var json = @"{""key1"":""value1"",""key2"":""value2""}";
var values = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
Run Code Online (Sandbox Code Playgroud)
如果使用 .NET Standard 或 .NET Framework,也可在 NuGet 包System.Text.Json 中使用。
请务必阅读并理解:
dex*_*exy 16
如果您正在使用轻量级,无添加引用的方法,那么我刚写的这些代码可能会起作用(尽管我不能100%保证稳健性).
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))));
}
Run Code Online (Sandbox Code Playgroud)
[我意识到这违反了OP限制#1,但从技术上讲,你没有写它,我做了]
Fal*_*lko 15
我只需要解析一个嵌套字典,比如
{
"x": {
"a": 1,
"b": 2,
"c": 3
}
}
Run Code Online (Sandbox Code Playgroud)
哪里JsonConvert.DeserializeObject没有帮助.我找到了以下方法:
var dict = JObject.Parse(json).SelectToken("x").ToObject<Dictionary<string, int>>();
Run Code Online (Sandbox Code Playgroud)
将SelectToken让你挖掘到所需的字段.您甚至可以指定一个类似于"x.y.z"进一步向下进入JSON对象的路径.
对于任何试图将 JSON 转换为字典只是为了从中检索一些值的人。有一个简单的方法使用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
Run Code Online (Sandbox Code Playgroud)
马克·雷德尔(Mark Rendle)将此作为评论发表,我想将其作为答案发表,因为它是迄今为止返回成功的唯一解决方案,并且是来自Google reCaptcha响应的错误代码json结果。
string jsonReponseString= wClient.DownloadString(requestUrl);
IDictionary<string, object> dict = new JavaScriptSerializer().DeserializeObject(jsonReponseString) as IDictionary<string, object>;
Run Code Online (Sandbox Code Playgroud)
再次感谢,马克!
编辑:这是有效的,但使用Json.NET接受的答案要简单得多.离开这个以防万一有人需要BCL专用代码.
开箱即用的.NET框架不支持它.一个明显的疏忽 - 不是每个人都需要反序列化为具有命名属性的对象.所以我最终滚动自己:
<Serializable()> 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
Run Code Online (Sandbox Code Playgroud)
叫:
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"]);
Run Code Online (Sandbox Code Playgroud)
对不起C#和VB.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;
}
Run Code Online (Sandbox Code Playgroud)