【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
我在JSON中有一个简单的键/值列表,该列表通过POST发送回ASP.NET。 例:
{ "key1": "value1", "key2": "value2"}
我不打算将序列化为严格类型的.NET对象
我只需要一个普通的旧Dictionary(Of String,String)或某些等效项(哈希表,Dictionary(Of String,Object),老式的StringDictionary-地狱,二维字符串数组对我来说就可以工作。
我可以使用ASP.NET 3.5以及流行的Json.NET(我已经在使用它序列化到客户端)中使用的任何东西。
显然,这两个JSON库都不具有这种开箱即用的明显功能-它们完全专注于通过强合同进行基于反射的反序列化。
有任何想法吗?
局限性:
- 我不想实现自己的JSON解析器
- 尚不能使用ASP.NET 4.0
- 希望远离JSON不再使用的旧的ASP.NET类
#1楼
十分烦人的是,如果您要使用默认的模型绑定程序,则看起来您将不得不使用数字索引值(如POST表单)。
请参阅本文的以下摘录http://msdn.microsoft.com/zh-cn/magazine/hh781022.aspx :
尽管有点违反直觉,但JSON请求具有相同的要求-它们也必须遵守表单后命名语法。 以上一个UnitPrice集合的JSON有效负载为例。 此数据的纯JSON数组语法将表示为:
[ { "Code": "USD", "Amount": 100.00 }, { "Code": "EUR", "Amount": 73.64 } ]
但是,默认值提供程序和模型联编程序要求将数据表示为JSON表单发布:
{ "UnitPrice[0].Code": "USD", "UnitPrice[0].Amount": 100.00, "UnitPrice[1].Code": "EUR", "UnitPrice[1].Amount": 73.64 }
复杂的对象集合方案可能是开发人员遇到的最广泛问题的方案之一,因为语法不一定对所有开发人员都显而易见。 但是,一旦您了解了用于发布复杂集合的相对简单的语法,这些情况就会变得更加容易处理。
#2楼
编辑:这可行,但是使用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
致电:
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的组合…
#3楼
Json.NET做到了...
string json = @"{""key1"":""value1"",""key2"":""value2""}";
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
更多示例: 使用Json.NET序列化集合
#4楼
如果您追求一种轻量级的,无添加引用的方法,那么也许我刚刚编写的这段代码会起作用(不过,我不能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))));
}
[我意识到这违反了OP限制#1,但从技术上讲,您没有编写它,我确实这样做了]
#5楼
我只是在RestSharp中实现了这一点 。 这篇文章对我很有帮助。
除了链接中的代码,这是我的代码。 当我执行以下操作时,我现在得到了结果Dictionary
:
var jsonClient = new RestClient(url.Host);
jsonClient.AddHandler("application/json", new DynamicJsonDeserializer());
var jsonRequest = new RestRequest(url.Query, Method.GET);
Dictionary<string, dynamic> response = jsonClient.Execute<JObject>(jsonRequest).Data.ToObject<Dictionary<string, dynamic>>();
请注意您期望的JSON类型-在我的情况下,我正在检索具有多个属性的单个对象。 在附件的链接中,作者正在检索列表。
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3149216