У меня проблемы с отображением данных API для метки в форме окна - PullRequest
0 голосов
/ 03 мая 2019

Я пытаюсь создать код для отображения типов, порядка и королевства организмов в lblOrganismIdentity. Во-первых, пользователь должен ввести название вида в tbNameSpecies. А затем нажмите btProcess, чтобы запустить метод класса Organism. И имя используется для создания ссылки API. Данные API находятся, например, в этой ссылке . Я не знаю, как сделать данные массивом, а затем отобразить их в lblOrganismIdentity.

Сообщение об ошибке исключения:

System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the dictionary.'

В этом коде возникает ошибка исключения

JsonObject kingdom = (JsonObject)gbifObj["kingdom"];

Я использую RestSharp и SimpleJson для ссылок. Я пытался найти решения, но не получил этого.

Это исходный код.

Метод GetOrganismList в классе Organism.cs

public static List<string> GetOrganismList(string link)
    {
        List<string> returnList = new List<string>();
        var client = new RestClient(link);
        var request = new RestRequest(Method.GET);
        IRestResponse response = client.Execute(request);
        JsonObject gbifObj = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(response.Content);
        Console.WriteLine(gbifObj); 
        JsonObject kingdom = (JsonObject)gbifObj["kingdom"];
        JsonObject phylum = (JsonObject)gbifObj["phylum"];
        JsonObject order = (JsonObject)gbifObj["order"];
        returnList.Add((string)kingdom["kingdom"]);
        returnList.Add((string)phylum["phylum"]);
        returnList.Add((string)order["order"]);
        return returnList;
    }

Form1.cs

    public Form1()
    {
        InitializeComponent();
    }

    List<string> identityList = new List<string>();
    private IEnumerable<string> identitylist;

    private void btProcess_Click(object sender, EventArgs e)
    {
        DisplayInfo(identityList);

    }

    private void DisplayInfo(List<string> identityList)
    {
        string link = "http://api.gbif.org/v1/species/match?&name=" + tbNameSpecies.Text.ToString();
        identityList = Organism.GetOrganismList(link);
        lblOrganismIdentity.Text = "";
        foreach (string item in identityList)
        {
            lblOrganismIdentity.Text += "- " + item + Environment.NewLine;
        }
    }

Я ожидаю, что lblOrganismIdentity может отображать данные вида из пользовательского ввода. Например:

королевство: Animalia

тип: Chordata

заказ: плотоядное животное

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Сначала необходимо десериализовать JSON в класс, например, Organism class. Сначала скопируйте наш пример файла JSON. И тогда мы можем использовать Edit --> Paste Special --> Paste JSON as classes.

Итак, класс будет таким.

public class Organism
{
    public int usageKey { get; set; }
    public string scientificName { get; set; }
    public string canonicalName { get; set; }
    public string rank { get; set; }
    public string status { get; set; }
    public int confidence { get; set; }
    public string matchType { get; set; }
    public string kingdom { get; set; }
    public string phylum { get; set; }
    public string order { get; set; }
    public string family { get; set; }
    public string genus { get; set; }
    public string species { get; set; }
    public int kingdomKey { get; set; }
    public int phylumKey { get; set; }
    public int classKey { get; set; }
    public int orderKey { get; set; }
    public int familyKey { get; set; }
    public int genusKey { get; set; }
    public int speciesKey { get; set; }
    public bool synonym { get; set; }
    public string _class { get; set; }
}

После этого мы теперь можем обращаться к свойствам класса для этого объекта как обычно.

    public static List<string> GetOrganismList(string link)
    {
        List<string> returnList = new List<string>();
        var client = new RestClient(link);
        var request = new RestRequest(Method.GET);
        IRestResponse response = client.Execute(request);
        var listOrganism = JsonConvert.DeserializeObject<Organism>(response.Content);

        returnList.Add(" Kingdom: " + listOrganism.kingdom.ToString());
        returnList.Add(" Phylum: " + listOrganism.phylum.ToString());
        returnList.Add(" Order: " + listOrganism.order.ToString());
        returnList.Add(" Family: " + listOrganism.family.ToString());
        returnList.Add(" Genus: " + listOrganism.genus.ToString());
        returnList.Add(" Species: " + listOrganism.species.ToString());

        return returnList;
    }
0 голосов
/ 03 мая 2019

Я заставил его работать в простом консольном приложении путем десериализации ожидаемого объекта: обратите внимание, что я отображал значение в консольном приложении, так как не смог создать новую форму выигрыша:

создать класс для возвращаемого объекта. Это более чисто.

class Animal {
    public int usageKey { get; set; }
    public int acceptedUsageKey { get; set; }
    public string scientificName { get; set; }
    public string canonicalName { get; set; }
    public string rank { get; set; }
    public string status { get; set; }
    public int confidence { get; set; }
    public string matchType { get; set; }
    public string kingdom { get; set; }
    public string phylum { get; set; }
    public int kingdomKey { get; set; }
    public int phylumKey { get; set; }
    public bool synonym { get; set; }
}

Вот способ получить значение из API и что-то с ним сделать

async void AsyncToConsole(Uri uri, Action<Animal> action) {

    using (var client = new HttpClient())
    {
        var getReg = await client.GetAsync(uri);
        var json = await getReg.Content.ReadAsStringAsync();                
        Animal animal;
        try
        {
            animal = (SimpleJson.DeserializeObject<Animal>(json));
            action(animal);
        }
        catch (Exception)
        {
            action(new Animal() { kingdom = "error", confidence = 0, phylum = "error" });
        }
    }
}

Основной метод, вроде как обработчик события щелчка формы

static void Main(string[] args)
{
    var species = "Lycopodiophyta";
    var uri = new Uri($"http://api.gbif.org/v1/species/match?&name={ species }");

    // callable method to display the values. like your foreach loop
    // it will be passed to the async method, who will then call it instead.
    Action<Animal> populateLabel = (Animal animal) =>
    {
        Console.WriteLine($"- {animal.kingdom}");
        Console.WriteLine($"- {animal.phylum}");
        Console.WriteLine($"- {animal.rank}");
    };
    // I need to use new Program(), but you dont need to do that
    new Program().AsyncToConsole(uri, populateLabel );
    Console.ReadLine();
    return;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...