将 JObject 转换为动态对象
Posted
技术标签:
【中文标题】将 JObject 转换为动态对象【英文标题】:Converting JObject to a dynamic object 【发布时间】:2016-08-02 16:41:43 【问题描述】:我正在从 C# 调用一个 REST 端点,并且我正在接收被序列化为对象的 json。此对象的属性之一是动态属性。动态属性的值在服务器站点上设置为匿名对象,如下所示:
myObject.MyDynamicProp = new Id = "MyId2134", Name = "MyName" ;
在客户端站点上,来自 json 序列化的动态属性的值是一个包含以下值的 JObject:
"id": "MyId2134",
"Name": "MyName"
我希望能够像这样访问属性:
var s = myObject.MyDynamicProp.Name;
但它没有找到 Name 属性,而是我必须得到这样的值:
var s = myObject.MyDynamicProp["Name"].Value;
我尝试将 JObject 转换为像这样的动态对象,但它返回 JObject:
var dyn = myObject.MyDynamicProp.ToObject<dynamic>();
如何转换动态属性值以便可以直接调用其属性?
var s = myObject.MyDynamicProp.Name;
更新...
我跑了以下
dynamic d = JsonConvert.DeserializeObject("\"MyDynamicProp\": \"id\": \"MyId2134\", \"Name\": \"MyName\"");
string name = d.MyDynamicProp.Name;
这给了我以下错误:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: `Newtonsoft.Json.Linq.JObject' does not contain a definition for `MyDynamicProp'
at Microsoft.Scripting.Interpreter.ThrowInstruction.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00027]
我想补充一点,这是一个 Xamarin ios 项目,代码位于 PCL 库中。
我认为我的代码存在问题,但似乎无法在 Xamarin iOS 项目中使用动态类型。 https://developer.xamarin.com/guides/ios/advanced_topics/limitations/
【问题讨论】:
【参考方案1】:其实很简单。不要在JObject
上使用dynamic
而不是使用var
,你会没事的:
dynamic do = myObject.MyDynamicProp;
string name = do.Name;
来自您的片段:
dynamic d = JsonConvert.DeserializeObject("\"MyDynamicProp\": \"id\": \"MyId2134\", \"Name\": \"MyName\"");
string name = d.MyDynamicProp.Name;
Console.WriteLine(name); // writes MyName
为什么会这样:正如Richard 解释的那样,JObject
间接派生自实现IDynamicMetaObjectProvider
的JToken
。正是该接口允许dynamic
工作。
【讨论】:
为什么会这样:JObject
间接派生自实现IDynamicMetaObjectProvider
的JToken
。正是该接口允许dynamic
工作。
是的,确实如此。谢谢理查德。我可以将其附加到我的答案中吗?
感谢您的快速回复,但即使我使用 dynamic 而不是 var,我在调用该属性时也会收到“未知成员:名称”。
是Name
,不是name
。
我得到的确切异常是 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Newtonsoft.Json.Linq.JObject' does not contain a definition for
Name' ...【参考方案2】:
在android中创建一个linker.xml文件 和 BuildAction 到链接描述
然后粘贴下面的代码
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="Mono.Android">
<type fullname="Xamarin.Android.Net.AndroidClientHandler" preserve="all" />
</assembly>
<assembly fullname="mscorlib"></assembly>
<assembly fullname="System.Core"></assembly>
<assembly fullname="System.Runtime.Serialization"> </assembly>
<assembly fullname="Newtonsoft.Json"></assembly>
\
<assembly fullname="System.Reactive.Linq"></assembly>
<assembly fullname="System.Reactive.Interfaces"></assembly>
<assembly fullname="System.Xml"></assembly>
<assembly fullname="Xamarin.Forms.Core"></assembly>
</linker>
【讨论】:
以上是关于将 JObject 转换为动态对象的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型为“Newtonsoft.Json.Linq.JObject”的对象转换为类型“System.Collections.Generic.Dictionary`2[System.String,S
无法将“Newtonsoft.Json.Linq.JObject”类型的对象强制转换为“Newtonsoft.Json.Linq.JArray”