问题描述
我最近完成了Treehouse在线课程“ C#流和数据处理”,该课程中的一门课程展示了如何使用Webclient查询API并解析返回的数据。所示示例使用Microsoft Bing API检索有关足球运动员的数据,但我试图使用其他API(即USGS地震目录)创建自己的项目。它显示有关最近地震的数据: USGS Earthquake Catalog
我已经使Web客户端正常工作,并且正在获取返回数据。我已经为数据创建了一个新类并将其粘贴为JSON,但是我不确定为什么无法访问代码中的属性? 我想做的是运行一个循环以遍历数据并显示大小,位置和时间。
namespace Earthquakes
{
class Program
{
static void Main(string[] args)
{
GetEarthquakes();
}
public static void GetEarthquakes()
{
var webClient = new WebClient();
byte[] earthquakeBytes = webClient.DownloadData("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2020-08-01&endtime=2020-08-02");
var serializer = new JsonSerializer();
using (var stream = new MemoryStream(earthquakeBytes))
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
string jsonString = "";
var earthquake = JsonConvert.DeserializeObject<Earthquakes>(jsonString);
Console.WriteLine(earthquake.Metadata.title);
}
}
}
}
和班级
namespace Earthquakes
{
public class Metadata
{
public long Generated { get; set; }
public string url { get; set; }
public string title { get; set; }
public int status { get; set; }
public string api { get; set; }
public int count { get; set; }
}
public class Properties
{
[JsonProperty("mag")]
public double Magnitude { get; set; }
[JsonProperty("place")]
public string Place { get; set; }
public object Time { get; set; }
public object Updated { get; set; }
public object Tz { get; set; }
public string Url { get; set; }
public string Detail { get; set; }
public int? Felt { get; set; }
public double? Cdi { get; set; }
public double? Mmi { get; set; }
public string Alert { get; set; }
public string Status { get; set; }
public int Tsunami { get; set; }
public int Sig { get; set; }
public string Net { get; set; }
public string Code { get; set; }
public string Ids { get; set; }
public string Sources { get; set; }
public string Types { get; set; }
public int? Nst { get; set; }
public double? Dmin { get; set; }
public double Rms { get; set; }
public double? Gap { get; set; }
public string MagType { get; set; }
public string Type { get; set; }
public string Title { get; set; }
}
public class Geometry
{
public string type { get; set; }
public List<double> coordinates { get; set; }
}
public class Feature
{
public string type { get; set; }
public Properties properties { get; set; }
public Geometry geometry { get; set; }
public string id { get; set; }
}
public class Earthquakes
{
public string Type { get; set; }
public Metadata Metadata { get; set; }
public List<Feature> Features { get; set; }
public List<double> Bbox { get; set; }
}
}
解决方法
几点:
-
似乎代码中的主要问题是您完全忽略了正在下载的数据,而是反序列化了一个空字符串。实际上,您可以使用
DownloadString
而不是DownloadData
来简化代码。然后,您只需几行代码即可获取JSON并反序列化它:webClient.Encoding = Encoding.UTF8; var json = webClient.DownloadString("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2020-08-01&endtime=2020-08-02"); var quakes = JsonConvert.DeserializeObject<Earthquakes>(json);
-
如果您只对几件事感兴趣,则实际上不需要在JSON中包含所有内容的属性。如果您只想要幅度,位置和时间,那么您的模型类可以像这样简单:
class Earthquakes { public List<Feature> Features { get; set; } } class Feature { public Properties Properties { get; set; } } class Properties { [JsonProperty("mag")] public decimal Magnitude { get; set; } public string Place { get; set; } [JsonProperty("time")] public long TimeMs { get; set; } public DateTime Time => new DateTime(1970,1,DateTimeKind.Utc).AddMilliseconds(TimeMs); }
还要注意,我添加了一种便捷方法,可将
time
值从JSON转换为可读日期。 -
您有一个名为
Earthquakes
的命名空间和其中的一个类Earthquakes
。尽管这在C#中是合法的,但它使代码更难以理解。我建议重命名一个或另一个,以便它们不相同。例如,您可以重命名名称空间EarthquakeDemo
或重命名类EarthquakeInfo
。当然取决于您。另外,我建议使GetEarthquakes()
方法返回它获取的地震,而不是使它无效。然后,您可以将获取逻辑与显示逻辑分开。
这是一个有效的演示,其中应用了以上更改并添加了显示逻辑:https://dotnetfiddle.net/uRg48y