json 将JObject转换为动态对象

oknrviil  于 2023-06-25  发布在  其他
关注(0)|答案(3)|浏览(189)

我正在从C#调用REST端点,并收到json,它被序列化为一个对象。此对象的属性之一是动态属性。dynamic属性的值设置为服务器站点上的匿名对象,如下所示:

myObject.MyDynamicProp = new { Id = "MyId2134", Name = "MyName" };

在客户端站点上,来自json序列化的dynamic属性的值是包含以下值的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/

lsmd5eda

lsmd5eda1#

这其实很容易。而不是使用varJObject上使用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间接衍生自JToken,后者实现了IDynamicMetaObjectProvider。正是这个接口允许dynamic工作。

qltillow

qltillow2#

在android和BuildAction中创建linker.xml文件以链接描述
然后粘贴下面的代码

<?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>
0x6upsns

0x6upsns3#

用途:

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

帕特里克Hofman的答案不起作用的原因是因为某些编译器的魔力导致JsonConvert.DeserializeObject<dynamic>返回一个JObject。我不知道为什么会这样,但你的dynamic对象实际上是一个JObject。这就是为什么当您尝试用d.MyDynamicProp调用JObject时,程序会抛出RuntimeBinderException,说明JObject不包含dynamic属性。
我提出的解决方案通过确保它成功地反序列化为ExpandoObject(这是动态类型的有效形式),然后使用下一行将ExpandoObject转换为dynamic,这可以工作。
注意:我的代码是2行的原因。下面的代码将不起作用

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

这段代码将得到“优化”,并试图直接转换为dynamic类型,导致前面提到的错误。

相关问题