jsw*_*son 919 .net c# serialization json dynamic
有没有办法将JSON内容反序列化为C#4动态类型?为了使用DataContractJsonSerializer,跳过创建一堆类会很不错.
Dre*_*kes 636
如果您乐意依赖System.Web.Helpers
程序集,那么您可以使用Json
该类:
dynamic data = Json.Decode(json);
Run Code Online (Sandbox Code Playgroud)
它包含在MVC框架中,作为.NET 4框架的附加下载.如果有帮助的话,一定要给Vlad一个upvote!但是,如果您不能假设客户端环境包含此DLL,请继续阅读.
这里建议采用另一种反序列化方法.我稍微修改了代码以修复错误并适合我的编码风格.您只需要这个代码和System.Web.Extensions
项目的引用:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
public sealed class DynamicJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
}
#region Nested type: DynamicJsonObject
private sealed class DynamicJsonObject : DynamicObject
{
private readonly IDictionary<string, object> _dictionary;
public DynamicJsonObject(IDictionary<string, object> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
_dictionary = dictionary;
}
public override string ToString()
{
var sb = new StringBuilder("{");
ToString(sb);
return sb.ToString();
}
private void ToString(StringBuilder sb)
{
var firstInDictionary = true;
foreach (var pair in _dictionary)
{
if (!firstInDictionary)
sb.Append(",");
firstInDictionary = false;
var value = pair.Value;
var name = pair.Key;
if (value is string)
{
sb.AppendFormat("{0}:\"{1}\"", name, value);
}
else if (value is IDictionary<string, object>)
{
new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb);
}
else if (value is ArrayList)
{
sb.Append(name + ":[");
var firstInArray = true;
foreach (var arrayValue in (ArrayList)value)
{
if (!firstInArray)
sb.Append(",");
firstInArray = false;
if (arrayValue is IDictionary<string, object>)
new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb);
else if (arrayValue is string)
sb.AppendFormat("\"{0}\"", arrayValue);
else
sb.AppendFormat("{0}", arrayValue);
}
sb.Append("]");
}
else
{
sb.AppendFormat("{0}:{1}", name, value);
}
}
sb.Append("}");
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!_dictionary.TryGetValue(binder.Name, out result))
{
// return null to avoid exception. caller can check for null this way...
result = null;
return true;
}
result = WrapResultObject(result);
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1 && indexes[0] != null)
{
if (!_dictionary.TryGetValue(indexes[0].ToString(), out result))
{
// return null to avoid exception. caller can check for null this way...
result = null;
return true;
}
result = WrapResultObject(result);
return true;
}
return base.TryGetIndex(binder, indexes, out result);
}
private static object WrapResultObject(object result)
{
var dictionary = result as IDictionary<string, object>;
if (dictionary != null)
return new DynamicJsonObject(dictionary);
var arrayList = result as ArrayList;
if (arrayList != null && arrayList.Count > 0)
{
return arrayList[0] is IDictionary<string, object>
? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)))
: new List<object>(arrayList.Cast<object>());
}
return result;
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
string json = ...;
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
dynamic obj = serializer.Deserialize(json, typeof(object));
Run Code Online (Sandbox Code Playgroud)
所以,给定一个JSON字符串:
{
"Items":[
{ "Name":"Apple", "Price":12.3 },
{ "Name":"Grape", "Price":3.21 }
],
"Date":"21/11/2010"
}
Run Code Online (Sandbox Code Playgroud)
以下代码将在运行时运行:
dynamic data = serializer.Deserialize(json, typeof(object));
data.Date; // "21/11/2010"
data.Items.Count; // 2
data.Items[0].Name; // "Apple"
data.Items[0].Price; // 12.3 (as a decimal)
data.Items[1].Name; // "Grape"
data.Items[1].Price; // 3.21 (as a decimal)
Run Code Online (Sandbox Code Playgroud)
小智 586
使用Json.NET非常简单:
dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;
Run Code Online (Sandbox Code Playgroud)
另外using Newtonsoft.Json.Linq
:
dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = stuff.Name;
string address = stuff.Address.City;
Run Code Online (Sandbox Code Playgroud)
文档:使用动态查询JSON
Vla*_*scu 293
您可以使用System.Web.Helpers.Json执行此操作- 它的Decode方法返回一个动态对象,您可以根据需要进行遍历.
它包含在System.Web.Helpers程序集(.NET 4.0)中.
var dynamicObject = Json.Decode(jsonString);
Run Code Online (Sandbox Code Playgroud)
Pet*_*ong 80
.Net 4.0有一个内置库来执行此操作:
using System.Web.Script.Serialization;
JavaScriptSerializer jss = new JavaScriptSerializer();
var d = jss.Deserialize<dynamic>(str);
Run Code Online (Sandbox Code Playgroud)
这是最简单的方法.
İbr*_*lük 75
简单的"字符串json数据"到没有任何第三方dll的对象
WebClient client = new WebClient();
string getString = client.DownloadString("https://graph.facebook.com/zuck");
JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(getString);
string name = item["name"];
//note: JavaScriptSerializer in this namespaces
//System.Web.Script.Serialization.JavaScriptSerializer
Run Code Online (Sandbox Code Playgroud)
注意:您还可以使用自定义对象.
Personel item = serializer.Deserialize<Personel>(getString);
Run Code Online (Sandbox Code Playgroud)
Ten*_*giz 37
我来这里是为了寻找 .NET Core 的答案,没有任何第三方或额外的参考。ExpandoObject
如果与标准类一起使用,效果很好JsonSerializer
。这是对我有用的示例:
using System.Text.Json;
using System.Dynamic;
dynamic json = JsonSerializer.Deserialize<ExpandoObject>(jsonText);
Console.WriteLine(json.name);
Run Code Online (Sandbox Code Playgroud)
name
此代码打印出传递到该方法的 JSON 文本中存在的属性的字符串值Deserialize
。瞧 - 没有额外的库,什么也没有。只是.NET 核心。
编辑:对于具有嵌套元素的多个级别的 json 可能存在问题。适用于单层平面对象。
jbt*_*ule 28
JsonFx可以将json反序列化为动态对象.
https://github.com/jsonfx/jsonfx
序列化到/从动态类型(.NET 4.0的默认值):
var reader = new JsonReader(); var writer = new JsonWriter();
string input = @"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }";
dynamic output = reader.Read(input);
Console.WriteLine(output.array[0]); // 42
string json = writer.Write(output);
Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]}
Run Code Online (Sandbox Code Playgroud)
小智 18
我创建了一个使用Expando Objects的DynamicJsonConverter的新版本.我使用了expando对象,因为我想使用Json.net将动态序列化为json.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Web.Script.Serialization;
public static class DynamicJson
{
public static dynamic Parse(string json)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic;
return glossaryEntry;
}
class DynamicJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
var result = ToExpando(dictionary);
return type == typeof(object) ? result : null;
}
private static ExpandoObject ToExpando(IDictionary<string, object> dictionary)
{
var result = new ExpandoObject();
var dic = result as IDictionary<String, object>;
foreach (var item in dictionary)
{
var valueAsDic = item.Value as IDictionary<string, object>;
if (valueAsDic != null)
{
dic.Add(item.Key, ToExpando(valueAsDic));
continue;
}
var arrayList = item.Value as ArrayList;
if (arrayList != null && arrayList.Count > 0)
{
dic.Add(item.Key, ToExpando(arrayList));
continue;
}
dic.Add(item.Key, item.Value);
}
return result;
}
private static ArrayList ToExpando(ArrayList obj)
{
ArrayList result = new ArrayList();
foreach (var item in obj)
{
var valueAsDic = item as IDictionary<string, object>;
if (valueAsDic != null)
{
result.Add(ToExpando(valueAsDic));
continue;
}
var arrayList = item as ArrayList;
if (arrayList != null && arrayList.Count > 0)
{
result.Add(ToExpando(arrayList));
continue;
}
result.Add(item);
}
return result;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*ren 17
使用Newtonsoft.Json的另一种方法:
dynamic stuff = Newtonsoft.Json.JsonConvert.DeserializeObject("{ color: 'red', value: 5 }");
string color = stuff.color;
int value = stuff.value;
Run Code Online (Sandbox Code Playgroud)
小智 10
使用Newtonsoft.Json创建动态对象真的很棒。
//json is your string containing the JSON value
dynamic data = JsonConvert.DeserializeObject<dynamic>(json);
Run Code Online (Sandbox Code Playgroud)
现在您可以data
像访问常规对象一样访问该对象。这是我们目前拥有的 JSON 对象作为示例:
{ "ID":123,"Name":"Jack","Numbers":[1, 2, 3] }
Run Code Online (Sandbox Code Playgroud)
这是反序列化后访问它的方式:
data.ID //Retrieve the int
data.Name //Retrieve the string
data.Numbers[0] //Retrieve the first element in the array
Run Code Online (Sandbox Code Playgroud)
您可以借助Newtonsoft.Json来实现。从Nuget安装Newtonsoft.Json和:
using Newtonsoft.Json;
dynamic results = JsonConvert.DeserializeObject<dynamic>(YOUR_JSON);
Run Code Online (Sandbox Code Playgroud)
最简单的方法是
只需包含此dll
使用这样的代码
dynamic json = new JDynamic("{a:'abc'}");
// json.a is a string "abc"
dynamic json = new JDynamic("{a:3.1416}");
// json.a is 3.1416m
dynamic json = new JDynamic("{a:1}");
// json.a is
dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
// And you can use json[0]/ json[2] to get the elements
dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
// And you can use json.a[0]/ json.a[2] to get the elements
dynamic json = new JDynamic("[{b:1},{c:1}]");
// json.Length/json.Count is 2.
// And you can use the json[0].b/json[1].c to get the num.
Run Code Online (Sandbox Code Playgroud)
您可以扩展JavaScriptSerializer以递归方式将其创建的字典复制到expando对象,然后动态使用它们:
static class JavaScriptSerializerExtensions
{
public static dynamic DeserializeDynamic(this JavaScriptSerializer serializer, string value)
{
var dictionary = serializer.Deserialize<IDictionary<string, object>>(value);
return GetExpando(dictionary);
}
private static ExpandoObject GetExpando(IDictionary<string, object> dictionary)
{
var expando = (IDictionary<string, object>)new ExpandoObject();
foreach (var item in dictionary)
{
var innerDictionary = item.Value as IDictionary<string, object>;
if (innerDictionary != null)
{
expando.Add(item.Key, GetExpando(innerDictionary));
}
else
{
expando.Add(item.Key, item.Value);
}
}
return (ExpandoObject)expando;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你只需要为你定义扩展的命名空间使用using语句(考虑在System.Web.Script.Serialization中定义它们......另一个技巧是不使用命名空间,那么你不需要使用完全声明)你可以像这样消费它们:
var serializer = new JavaScriptSerializer();
var value = serializer.DeserializeDynamic("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
var name = (string)value.Name; // Jon Smith
var age = (int)value.Age; // 42
var address = value.Address;
var city = (string)address.City; // New York
var state = (string)address.State; // NY
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以使用 using Newtonsoft.Json
var jRoot =
JsonConvert.DeserializeObject<dynamic>(Encoding.UTF8.GetString(resolvedEvent.Event.Data));
Run Code Online (Sandbox Code Playgroud)
resolvedEvent.Event.Data
是我从调用核心事件得到的回应.
小智 6
另一种选择是“将 JSON 粘贴为类”,以便快速轻松地反序列化。
这是一个更好的解释 n piccas... ASP.NET and Web Tools 2012.2 RC 中的“Paste JSON As Classes”
我想在单元测试中以编程方式执行此操作,我确实可以将其打印出来。
我的解决方案是:
var dict = JsonConvert.DeserializeObject<ExpandoObject>(json) as IDictionary<string, object>;
Run Code Online (Sandbox Code Playgroud)
现在我可以断言
dict.ContainsKey("ExpectedProperty");
Run Code Online (Sandbox Code Playgroud)
看看我在CodeProject上写的文章,它准确地回答了这个问题:
在这里重新发布所有内容的方式太多了,甚至更少一点,因为该文章附带了密钥/所需的源文件.
小智 5
尝试这个:
var units = new { Name = "Phone", Color= "White" };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, units);
Run Code Online (Sandbox Code Playgroud)
JSON.NET 中的反序列化可以使用JObject
该库中包含的类动态进行。我的 JSON 字符串代表这些类:
public class Foo {
public int Age {get;set;}
public Bar Bar {get;set;}
}
public class Bar {
public DateTime BDay {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
现在我们反序列化字符串而不引用上述类:
var dyn = JsonConvert.DeserializeObject<JObject>(jsonAsFooString);
JProperty propAge = dyn.Properties().FirstOrDefault(i=>i.Name == "Age");
if(propAge != null) {
int age = int.Parse(propAge.Value.ToString());
Console.WriteLine("age=" + age);
}
//or as a one-liner:
int myage = int.Parse(dyn.Properties().First(i=>i.Name == "Age").Value.ToString());
Run Code Online (Sandbox Code Playgroud)
或者如果你想更深入:
var propBar = dyn.Properties().FirstOrDefault(i=>i.Name == "Bar");
if(propBar != null) {
JObject o = (JObject)propBar.First();
var propBDay = o.Properties().FirstOrDefault (i => i.Name=="BDay");
if(propBDay != null) {
DateTime bday = DateTime.Parse(propBDay.Value.ToString());
Console.WriteLine("birthday=" + bday.ToString("MM/dd/yyyy"));
}
}
//or as a one-liner:
DateTime mybday = DateTime.Parse(((JObject)dyn.Properties().First(i=>i.Name == "Bar").First()).Properties().First(i=>i.Name == "BDay").Value.ToString());
Run Code Online (Sandbox Code Playgroud)
请参阅帖子了解完整示例。
我在我的代码中使用这样的,它工作正常
using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);
Run Code Online (Sandbox Code Playgroud)
我使用:http: //json2csharp.com/ 来获取一个代表Json对象的类.
输入:
{
"name":"John",
"age":31,
"city":"New York",
"Childs":[
{
"name":"Jim",
"age":11
},
{
"name":"Tim",
"age":9
}
]
}
Run Code Online (Sandbox Code Playgroud)
输出:
public class Child
{
public string name { get; set; }
public int age { get; set; }
}
public class Person
{
public string name { get; set; }
public int age { get; set; }
public string city { get; set; }
public List<Child> Childs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
之后我使用Newtonsoft.Json来填充类:
using Newtonsoft.Json;
namespace GitRepositoryCreator.Common
{
class JObjects
{
public static string Get(object p_object)
{
return JsonConvert.SerializeObject(p_object);
}
internal static T Get<T>(string p_object)
{
return JsonConvert.DeserializeObject<T>(p_object);
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼它:
Person jsonClass = JObjects.Get<Person>(stringJson);
string stringJson = JObjects.Get(jsonClass);
Run Code Online (Sandbox Code Playgroud)
PS:
如果您的json变量名称没有有效的C#名称(名称以...开头$
),您可以像这样修复:
public class Exception
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
public object innerException { get; set; }
public string message { get; set; }
public string typeName { get; set; }
public string typeKey { get; set; }
public int errorCode { get; set; }
public int eventId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
672734 次 |
最近记录: |