【问题标题】:Geocoding REST call C# Parsing JSON地理编码 REST 调用 C# 解析 JSON
【发布时间】:2018-12-15 18:54:59
【问题描述】:

我正在努力获取从下面的地理编码 REST 调用返回的数据(我已删除我的 app_id 和 app_code,因此您无法运行下面的 url):

https://geocoder.api.here.com/6.2/geocode.json?app_id=[MYAPP ID]&app_code=[我的APP代码]&searchtext=chester

可以在此处找到示例响应:

https://developer.here.com/documentation/geocoder/topics/quick-start-geocode.html

我知道它会返回结果,但我似乎无法将结果传递给我的 C# 应用程序,我不知道我是否错误地构建了类系统,或者我是否做错了什么。我之前已经构建了一个应用程序来读取位置 api,但这个应用程序似乎有所不同。

调用返回正常状态:

public void GeoCode()
    {
        // BUILD INITIAL STRING BASED ON PARAMETERS
        string url = "https://geocoder.api.here.com/6.2/geocode.json?app_id=gpZ1Ym7rwuXs6Xj1TsD8&app_code=4UXmaGFTe30LttFgOY7iqQ&searchtext=" + tbLoc.text;
        // RUN THE ASYNCRONOUS COMMAND (I THINK)
        StartCoroutine(GetText(url));
    }

    IEnumerator GetText(string url)
    {
        // CREATE WEB REQUEST WITH SPECIFIED URL
        UnityWebRequest www = UnityWebRequest.Get(url);
        // RETURN RESULTS FROM ASYNC COMMAND
        yield return www.SendWebRequest();
        // PARSE JSON RESPONSE
        RootObject RootObject = JsonUtility.FromJson<RootObject>(www.downloadHandler.text);
        // IF 200 (STATUS OKAY) GATHER RESULTS, ELSE RETURN ERROR
        if (www.responseCode == 200)
        {
            BuildArray(RootObject);
        }
        else
        {
            Debug.Log("Call Failed With Error: " + www.responseCode.ToString());
        }
    }

    private void BuildArray(RootObject RootObject)
    {
        print(RootObject.Response.View[0].Result[0].Location.Address.Label);
    }

它尝试运行 BuildArray 函数,但这会返回一个空引用。 (我只是用 NextPageInformation 作为最基本的选项来测试)

下面是我为处理 JSON 而构建的类结构:

    public class Address
    {
        public string Label { get; set; }
    }

    public class Location
    {
        public Address Address { get; set; }
    }

    public class Result
    {
        public Location Location { get; set; }
    }

    public class View
    {
        public List<Result> Result { get; set; }
    }

    public class Response
    {
        public List<View> View { get; set; }
    }

    public class RootObject
    {
        public Response Response { get; set; }
    }

有人可以帮忙吗? 谢谢

【问题讨论】:

  • 如果我不得不用一堆 json 做某事,我会复制它,并将其粘贴到 QuickType.io 并让它生成一组类和使用说明,然后将其放回我的程序。 QuickType 非常好,我很想将其作为答案发布,但外部资源有些短暂,并不总是能提供好的 SO 答案。然而,它应该是解决这个问题的一站式服务,包括一些类似“将这行代码粘贴到你的应用程序中,它就可以正常工作”的帮助代码生成

标签: c# json rest here-api


【解决方案1】:

如果您只想从 json 中解析一个键值对,那么创建类结构对您来说将是一项繁琐的工作。

您可以Querying a json with Newtonsoft,而不是创建类结构。

  1. 解析您的 json。
  2. 查询已解析的 json 以检索 Label 价值。

//1
JToken jToken = JToken.Parse(jsonString);

//2
string label = jToken["Response"]["View"][0]["Result"][0]["Location"]["Address"]["Label"].ToObject<string>();

Console.WriteLine(label);

Console.ReadLine();

输出:(来自链接中提供的示例 json)

注意:您需要从 nuget 安装 newtonsoft.json 包并将以下命名空间添加到您的程序中。

using Newtonsoft.Json.Linq;

编辑:

如果你想解析完整的 json,那么首先创建一个如下所示的类结构

public class MetaInfo
{
    public DateTime Timestamp { get; set; }
}

public class MatchQuality
{
    public int City { get; set; }
    public List<double> Street { get; set; }
    public int HouseNumber { get; set; }
}

public class DisplayPosition
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class NavigationPosition
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class TopLeft
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class BottomRight
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class MapView
{
    public TopLeft TopLeft { get; set; }
    public BottomRight BottomRight { get; set; }
}

public class AdditionalData
{
    public string value { get; set; }
    public string key { get; set; }
}

public class Address
{
    public string Label { get; set; }
    public string Country { get; set; }
    public string State { get; set; }
    public string County { get; set; }
    public string City { get; set; }
    public string District { get; set; }
    public string Street { get; set; }
    public string HouseNumber { get; set; }
    public string PostalCode { get; set; }
    public List<AdditionalData> AdditionalData { get; set; }
}

public class Location
{
    public string LocationId { get; set; }
    public string LocationType { get; set; }
    public DisplayPosition DisplayPosition { get; set; }
    public List<NavigationPosition> NavigationPosition { get; set; }
    public MapView MapView { get; set; }
    public Address Address { get; set; }
}

public class Result
{
    public int Relevance { get; set; }
    public string MatchLevel { get; set; }
    public MatchQuality MatchQuality { get; set; }
    public string MatchType { get; set; }
    public Location Location { get; set; }
}

public class View
{
    public string _type { get; set; }
    public int ViewId { get; set; }
    public List<Result> Result { get; set; }
}

public class Response
{
    public MetaInfo MetaInfo { get; set; }
    public List<View> View { get; set; }
}

public class RootObject
{
    public Response Response { get; set; }
}

然后你就可以反序列化你的json了。

RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);

注意:您需要将以下命名空间添加到您的程序中。

using Newtonsoft.Json;

【讨论】:

  • 我实际上使用了响应中的很多元素,这只是我正在使用的测试行,直到我可以正确读取它。不过现在有几个人提到了 Newtonsoft,所以我会试一试,谢谢。
  • @KyleJackson,对于您的其他几个元素,您可以使用我上面给您的相同方法,如果您想解析完整响应,那么我会尽快更新我的答案......如果我的回答有帮助然后标记答案左侧的勾号使其变为绿色... :)
  • @KyleJackson,答案已更新。请查看答案中的 Edit: 部分:)
【解决方案2】:

我个人在使用 JsonUtility 解析嵌套的 json 对象时遇到问题。所以我切换到 Newtonsoft Json,它工作得非常好。 在您的情况下,您需要使用 [Serializable] see here

将类标记为序列化
[Serializable] 
public class Address
    {
        public string Label;
    }

【讨论】:

  • 嗨,我已经在 Serializable 中添加了,就像我在之前的 JSON 调用中所做的一样(我不知道这次我是怎么忘记包含它的!)但我仍然得到标签上的空引用。
  • 你能把 JSON 粘贴到这里吗?
  • 还有一件事,您正在创建 RootObject 类型的 RootObject,您可能需要将其更改为 rootObject
  • 我在原帖中粘贴了 JSON 的示例,谢谢
猜你喜欢
  • 2011-09-28
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多