将JObject转换为动态对象



我正在从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/

这其实很容易。不使用var,而是在JObject上使用dynamic,这样就可以了:

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间接派生自实现IDynamicMetaObjectProviderJToken。正是这个接口允许dynamic工作。

在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>

使用:

var expanded = JsonConvert.DeserializeObject<ExpandoObject>("{ ... }");
dynamic dynamicData = expanded;

Patrick Hofman的答案不起作用的原因是某些编译器的魔力导致JsonConvert.DeserializeObject<dynamic>返回JObject。我不知道为什么会这样,但你的dynamic对象实际上是一个秘密的JObject。这就是为什么当您尝试用d.MyDynamicProp调用程序时,程序抛出RuntimeBinderException,说JObject不包含动态属性。

我提出的解决方案通过确保它成功地反序列化为ExpandoObject(这就是动态类型的有效含义)来修复这一问题,然后使用下一行将ExpandoObject强制转换为dynamic,这是有效的。

注意:我的代码是2行,这是有原因的。下面的代码将不起作用

dynamic dynamicData = JsonConvert.DeserializeObject<ExpandoObject>("{ ... }");

此代码将被"优化",并尝试直接转换为dynamic类型,从而导致前面提到的错误。

相关内容

  • 没有找到相关文章

最新更新