【问题标题】:JSON to object C# (mapping complex API response to C# object)JSON 到 C# 对象(将复杂的 API 响应映射到 C# 对象)
【发布时间】:2017-09-08 13:40:10
【问题描述】:

我能够处理简单的 JSON 序列化和反序列化,但这个 API 响应似乎有点复杂,我正在寻求解决这个问题的理想方法的建议。

我正在尝试为 MVC 应用程序调用 API。 目标是将 API 数据映射到模型。 API端点是 https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=MyAPIKey

这里的问题是:

  1. JSON 数据键中有空格。
  2. 当我尝试在 Visual Studio 中进行特殊粘贴时,它给了我很长时间 每个日期条目的类列表分别,因为这个 API call 返回一组单独的日期信息。

为了解决第 1 点中解释的问题,我在课堂上使用了[JsonProperty("1. Information")]。在我的代码中..

        public async Task TSI()
        {
            HttpClient client = new HttpClient();
            //Uri uri = new Uri("http://date.jsontest.com/");
            Uri uri = new Uri("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=5min&apikey=demo");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                dynamic result = await response.Content.ReadAsAsync<object>();

                IEnumerable<dynamic> dObj = JsonConvert.DeserializeObject<dynamic>(result.ToString());

                IEnumerable<dynamic> t1 = dObj.FirstOrDefault();
                IEnumerable<dynamic> t2 = dObj.LastOrDefault();
                dynamic MetaData = t1.FirstOrDefault();

                Rootobject ro = new Rootobject();
                ro.MetaData = MetaData;

            }

PS:我对 API 调用和处理比较陌生。

我可以打电话给

date.jsontest.com

并将 API 数据映射到模型(我使用特殊粘贴创建的)

//API response
    {
        "time": "12:53:22 PM",
        "milliseconds_since_epoch": 1504875202754,
        "date": "09-08-2017"
    }

//C# code to map to API data
    public class sampleObject
    {
        public string time { get; set; }
        public long milliseconds_since_epoch { get; set; }
        public string date { get; set; }
    }

我的 RootObject 如下所示:

public class Rootobject
    {
        [JsonProperty("Meta Data")]
        public MetaData MetaData { get; set; }

        [JsonProperty("Time Series (1min)")]
        public TimeSeries1Min TimeSeries1min { get; set; }
    }

    public class MetaData
    {
        [JsonProperty("1. Information")]
        public string _1Information { get; set; }

        [JsonProperty("2. Symbol")]
        public string _2Symbol { get; set; }

        [JsonProperty("3. Last Refreshed")]
        public string _3LastRefreshed { get; set; }

        [JsonProperty("4. Interval")]
        public string _4Interval { get; set; }

        [JsonProperty("5. Output Size")]
        public string _5OutputSize { get; set; }

        [JsonProperty("6. Time Zone")]
        public string _6TimeZone { get; set; }
    }

// I have so many of these sub-classes for dates, which again is an issue
    public class TimeSeries1Min
    {
            public _20170907160000 _20170907160000 { get; set; }
            public _20170907155900 _20170907155900 { get; set; }
....
....}



public class _20170907160000
    {
        public string _1open { get; set; }
        public string _2high { get; set; }
        public string _3low { get; set; }
        public string _4close { get; set; }
        public string _5volume { get; set; }
    }

    public class _20170907155900
    {
        public string _1open { get; set; }
        public string _2high { get; set; }
        public string _3low { get; set; }
        public string _4close { get; set; }
        public string _5volume { get; set; }
    }

【问题讨论】:

  • 我明白,对于这个问题的所有混乱和复杂性,我很抱歉。到目前为止,我得到的答案让我进步了一点。关于 JSON 解析,我能够序列化和反序列化简单的 JSON 数据。但这一个太复杂了,我想知道是否有人对此有好的方法。我可能很快就会结束这个问题:-)
  • @MatthiasBurger json2charp 产生垃圾(在这种情况下正如预期的那样)..
  • @L.B.只有当你是一个复制粘贴开发者:) (对不起,没有伤害),你需要检查和比较,但 json2csharp 可以完成它的工作。检查它是否合适是开发人员的工作。 :)
  • @MatthiasBurger 你见过它为有问题的 json 生成的模型吗?它不能像这样建模。另请阅读我与 json 相关的答案,以查看我何时使用该网站,何时不使用。 stackoverflow.com/search?q=user:932418+[json]
  • @Matt.. 感谢您收回反对票,我正在努力达到 15 个声誉:P

标签: c# api model-view-controller json.net


【解决方案1】:

很难从这个 json 创建模型,但你可以将这些数据转换为字典

var jObj = JObject.Parse(json);
var metadata = jObj["Meta Data"].ToObject<Dictionary<string, string>>();
var timeseries = jObj["Time Series (1min)"].ToObject<Dictionary<string, Dictionary<string, string>>>();

【讨论】:

  • 这似乎是一个很好的解决方案。元数据工作得很好,但第二个没有给出预期的结果。而且,我什至不知道这种方法。我认为响应太复杂而无法处理。
  • but the second one didn't give expected result 你期待什么,你得到了什么?它在一个字典中提供 100 个字典(即每个 Value 是另一个字典)。
  • 第一个字典一经处理就给了我预期的字典(我已经在该行设置了断点)。但是一旦第二行被击中,执行就会失败。
  • @JigarPatel 我在发布之前用你的 json 测试了上面的代码......你得到了什么错误?
  • 啊!我犯了一个愚蠢的错误,我在视觉工作室中的 Uri 的间隔设置为 5 分钟,而我在这里发布的是 1 分钟。我想我现在最好去睡觉,让我的头脑休息一下。谢谢你的回答。
【解决方案2】:

下面的代码应该做你想做的事

       if (response.IsSuccessStatusCode)
        {
            var result = await response.Content.ReadAsStringAsync();

            var obj = JsonConvert.DeserializeObject<Rootobject>(result);
            //No idea what you want to do with this line as there is no MetaData property on the root object
            obj.MetaData = MetaData;

        }

【讨论】:

  • 我很抱歉造成混乱。我将在一分钟内编辑一个问题。我已经更新了问题。
  • 嘿ObiEff,你的回答也对我有帮助。谢谢!
猜你喜欢
  • 2020-03-08
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多