【问题标题】:enumerate JSON properties in C# DalSoft.RestClient and/or Json.net枚举 C# DalSoft.RestClient 和/或 Json.net 中的 JSON 属性
【发布时间】:2018-04-17 18:38:25
【问题描述】:

作为一个简单的例子,试图让它在控制台应用程序中工作。 我正在使用来自 nuget 的 Json.NetDalSoft.RestClient 包。我没有与其中任何一个结婚,我只是想完成工作。接受替代方案。

http://jsonplaceholder.typicode.com/users 返回有效的 JSON。

我想提前列举出未知的属性。以下似乎可行,但因 System.AggregateException - RuntimeBinderException:无法在空引用上执行运行时绑定而失败 我觉得我错过了一些简单的事情。

using System;
using System.Threading.Tasks;
using DalSoft.RestClient;
using Newtonsoft.Json.Linq;

namespace ImTired
{
    class Program
    {
        static void Main(string[] args)
        {
            DoThingsAsync().Wait();
            Console.ReadLine();
        }

        private static async Task<object> DoThingsAsync()
        {
            dynamic client = new RestClient("http://jsonplaceholder.typicode.com");
            var user = await client.Users.Get();
            var foo = user[0].name; // grab the first item (Works to this point)

            //JProperty item = new JProperty(user);
            var item = user[0];

            foreach (JProperty property in item.Properties()) //(fails here I've missed a cast or conversion)
            {
                Console.WriteLine(property.Name + " - " + property.Value);
            }

            Console.WriteLine("Call Complete: " + foo);

            return null;
        }
    }
}


跟进编辑:为任何潜伏者添加了此内容。 我需要将程序集添加到 GAC 以使其可用于scripting tool。这是您的强名称信息。

我知道可能还有另一种更好的方法来引用非 GAC 程序集。我只是没有时间弄清楚。也许我会在这里提出一个有意义的问题。

有趣的结果:

【问题讨论】:

  • 应该item.Properties()item.properties() 还是item.properties?该错误听起来像是 .Properties() 是错误的调用方式,因为这将是您创建类的新实例的方式,而不是访问属性或方法的方式。
  • item.GetType().FullName 返回的item 的实际类型是什么? client.Users.Get() 返回的声明类型是什么?最后,异常的完整ToString() 输出是什么,包括异常类型、消息、回溯和内部异常(如果有)?

标签: c# json rest nuget-package dalsoft.restclient


【解决方案1】:

试试这个(我用的是 RestSharp):

 using System;
 using System.Threading.Tasks;
 using Newtonsoft.Json.Linq;
 using RestSharp;

 namespace ImNotSoTired
 {
    class Program
    {
         static void Main(string[] args)
         {
             DoThingsAsync().Wait();
             Console.ReadLine();
         }

         private static async Task<object> DoThingsAsync()
         {
             RestClient client = new RestClient("http://jsonplaceholder.typicode.com");
             var response = client.Execute(new RestRequest("users"));

             JArray users = JArray.Parse(response.Content);
             var user = (JObject)users[0];

             foreach (JProperty property in user.Properties())
             {
                 Console.WriteLine(property.Name + " - " + property.Value);
             }

             return null;
         }
     }
}

【讨论】:

  • 感谢这个有效的答案。 +1!我纠结于该把答案归功于谁。然而,我将切换到 RestSharp,因为它看起来是一个更成熟的产品。请继续提供高质量的答案。社区感谢您。
  • @JoeJohnston 他们解决了不同的问题,我的 RestClient 让您使用处理程序完全控制管道,并允许您在一行代码中转换为静态类型。
【解决方案2】:

DalSoft Rest Client 不暴露 JsObject/JsArray。它将 JSON 包装在 RestClientResponseObject 中,并使用 ToString 方法作为字符串公开。要获取所有 JSON 属性,我们需要将字符串显式解析为 JObject/JArray。

var item =JObject.Parse(user[0].ToString());
OR  
var users = JArray.Parse(user.ToString());
var item = users[0]; 

【讨论】:

  • 这是一个很好的解释为什么它不起作用以及如何修复它。为什么是我在这里给出答案的原因。尽管范德雷提供了一个完整的答案。
【解决方案3】:

DalSoft.RestClient 返回一个动态对象,或者您可以将其转换为一个类。文档中有这样的例子,让我知道是否有任何遗漏。

也可以在 gitter 频道上提问。

以下是您的代码工作。如果您需要返回属性名称,则必须先转换为静态类型,然后照常使用反射。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DalSoft.RestClient;

namespace ImTired
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                DoThingsAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            Console.ReadLine();
        }

        private static async Task<object> DoThingsAsync()
        {
            dynamic client = new RestClient("http://jsonplaceholder.typicode.com");
            List<User> users = await client.Users.Get();
            var foo = users[0].name; // grab the first item (Works to this point)

            var user = users[0]; 
            foreach (var propertyInfo in user.GetType().GetProperties())
            {
                Console.WriteLine(propertyInfo.Name + " - " + propertyInfo.GetValue(user));
            }

            return null;
        }        
    }

    public class User
    {
        public int id { get; set; }
        public string name { get; set; }
        public string username { get; set; }
        public string email { get; set; }
        public string phone { get; set; }
        public string website { get; set; }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多