【问题标题】:Not able to deserialize JSON response in C#无法在 C# 中反序列化 JSON 响应
【发布时间】:2018-10-18 09:10:35
【问题描述】:

所以我目前正在尝试反序列化 JSON API。 我正在使用与其他 API 成功使用的代码相同的代码。 但是每个变量都只返回 0。

    public class RootObject
{
    public int lat { get; set; }
    public int lon { get; set; }
    public DateTime date_iso { get; set; }
    public int date { get; set; }
    public double value { get; set; }
}

public class UVGetter
{
    public static async Task<RootObject> UVApiProxy(double lat, double lon)
    {
        var Timestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();

        var http = new HttpClient();
        string WeatherApiKey = "secret";
        var url = String.Format($"https://api.openweathermap.org/data/2.5/uvi/history?appid=" + WeatherApiKey + "&lat=" + Math.Round(lat) + "&lon=" + Math.Round(lon) + "&start=" + Timestamp + "&end=" + Timestamp);
        var response = await http.GetAsync(url);
        var result = await response.Content.ReadAsStringAsync();
        var serializer = new DataContractJsonSerializer(typeof(RootObject));

        var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
        var uvdata = (RootObject)serializer.ReadObject(ms);
        Agara.Program.WeatherApiCalls++;
        Console.WriteLine(uvdata.lat + "\n" + uvdata.lon + "\n" + uvdata.date_iso.ToString() + "\n" + uvdata.date + "\n" + uvdata.value);
        return uvdata;
    }
}

结果是这样的

[{"lat":54,"lon":9,"date_iso":"2018-05-08T12:00:00Z","date":1525780800,"value":5.62}]

并且变量(例如 uvdata.lat)只包含零,尽管 API 信息应该存储在这些变量中。

【问题讨论】:

  • 我推荐使用Json Nuget。易于使用和良好的错误处理。

标签: c# json api discord


【解决方案1】:

您的 json 字符串是一个数组而不是单个对象,因此您应该反序列化为数组。您也可以为此使用Newtonsoft.Json(恕我直言,它很容易使用),您只需复制您的json字符串并在VisualStudio中轻松创建class

编辑 -> PasteSpecial -> 将 JSON 粘贴为类

public class Rootobject
{
    public Class1[] Property1 { get; set; }
}

public class Class1
{
    public int lat { get; set; }
    public int lon { get; set; }
    public DateTime date_iso { get; set; }
    public int date { get; set; }
    public float value { get; set; }
}

string json  = @"[{""lat"":54,""lon"":9,""date_iso"":""2018 - 05 - 08T12: 00:00Z"",""date"":1525780800,""value"":5.62}]";
Class1[] result = JsonConvert.DeserializeObject<Class1[]>(json);

【讨论】:

  • 不是我的反对意见,但你的回答没有解释你改变了什么(除了使用不同的 JSON API),也没有解释为什么。 DataContractJsonSerializer 也可以轻松处理这种 JSON 格式。
  • 好吧..我没有改变任何东西,我只是说它易于使用,并显示一个示例。
  • 您确实改变了一些东西,即与我在回答中所做的相同,最终是 OP 的问题:RootObject -> RootObject[]
  • @CodeCaster RootObject 命名是由 VisualStudio 生成的,这只是巧合,在我的示例中它是 Class1[] 而不是 RootObject[]。但无论如何,谢谢你的注意,我已经更新了我的答案,我并不是说你不能用DataContractJsonSerializer 实现这一点,我只是说你可以使用Newtonsoft 的 json 反序列化器。
  • 我的意思不是名字……而是数组部分。感谢您添加。
【解决方案2】:

JSON 不包含RootObject,它是RootObject数组。所以:

var serializer = new DataContractJsonSerializer(typeof(RootObject[]))
// ...
var uvdata = (RootObject[])serializer.ReadObject(ms);

或者,使用Newtonsoft.Json:

var uvData = JsonConvert.DeserializeObject<RootObject[]>(result);

您还可以反序列化为 List&lt;RootObject&gt; 而不是数组。

如果要保留前导零,请将这些属性反序列化为字符串,因为整数没有这个概念,所以:

public class RootObject
{
    public string lat { get; set; }
    public string lon { get; set; }
    public DateTime date_iso { get; set; }
    public int date { get; set; }
    public double value { get; set; }
}

【讨论】:

  • [] 表示一个列表/数组,所以他可以同时使用
  • 是的,有很多集合类型。在反序列化时,虽然您几乎不需要修改集合,所以我更喜欢最简单的:一个数组。
猜你喜欢
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多