【问题标题】:Converting JObject to a dynamic object将 JObject 转换为动态对象
【发布时间】: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/

【问题讨论】:

    标签: c# json xamarin json.net


    【解决方案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 间接派生自实现IDynamicMetaObjectProviderJToken。正是该接口允许dynamic 工作。

    【讨论】:

    • 为什么会这样:JObject 间接派生自实现IDynamicMetaObjectProviderJToken。正是该接口允许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>
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-10-21
      • 2011-06-15
      相关资源
      最近更新 更多