首页 > 解决方案 > 无法在 WPF 表单上显示 Web API 响应

问题描述

我有一个项目,我一直在使用 RiotGames API,由于某种原因,我无法在我的 WPF 表单上显示 API 响应,我向 2 个不同的 API 发出了两个请求,其中只有一个显示在表单上。我不确定到底发生了什么,但任何反馈都会很好,不需要是一个完整的解决方案。

这是我的 MainWindow.xaml.cs 文件:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        initalProfileLoad();
        initalRankedLoad();
    }

    private async Task initalProfileLoad()
    {
        await APIConnect.getSummonerByName(Regions.NA, summoner, "Fusion Icee");
        this.tbSummonerName.Text = summoner.name;
        this.tbSummonerLevel.Text = summoner.summonerLevel.ToString();
    }

    private async Task initalRankedLoad()
    {
        var rHandler = new RankHandler();
        var rankedSummoner = new LSummonerRanked();

        await APIConnect.getSummonerRankBySummonerID(Regions.NA, rankedSummoner, summoner.id);
        this.tbRankDivision.Text = rankedSummoner.tier + "" + rankedSummoner.rank;
        this.imgRankedIcon.Source = new BitmapImage(new Uri(rHandler.getRankedIcon(rankedSummoner.tier).ToString()));
    }

我将这两个连接放入单独的方法中以用于加载目的,以防我最大化请求..

这是我的 APIConnect.cs 文件:

public static async Task getSummonerByName(Regions _rg, LSummoner summoner, string summonerName)
    {
        var summ = new LSummoner();

        using (HttpClient client = new HttpClient())
        {
            Region region = new Region();
            client.BaseAddress = new Uri("https://" + region.getRegionConnectionString(_rg));
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync($"{SUMMONER_API}{summonerName}?api_key={API_KEY}");
            if (response.IsSuccessStatusCode)
            {
                LSummoner lSummoner = await response.Content.ReadAsAsync<LSummoner>();
                summoner.name = lSummoner.name; summoner.profileIconId = lSummoner.profileIconId;
                summoner.puuid = lSummoner.puuid; summoner.summonerLevel = lSummoner.summonerLevel;
                summoner.revisionDate = lSummoner.revisionDate; summoner.id = lSummoner.id;
                summoner.accountId = lSummoner.accountId;
            }
            else
            {
                response.EnsureSuccessStatusCode();
            }
        }
    }

    /// <summary>
    /// Gets the summoner by an Encrypted Summoner ID from the RiotGames API
    /// </summary>
    /// <param name="_rg"></param>
    /// <param name="summoner"></param>
    /// <param name="encryptedSummonerID"></param>
    /// <returns></returns>
    static async Task getSummonerByid(Regions _rg, string encryptedSummonerID)
    {
        var summ = new LSummoner();

        using (HttpClient client = new HttpClient())
        {
            Region region = new Region();
            client.BaseAddress = new Uri("https://" + region.getRegionConnectionString(_rg));
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync($"/lol/summoner/v4/summoners/by-account/{encryptedSummonerID}?api_key={API_KEY}");
            if (response.IsSuccessStatusCode)
            {
                LSummoner lSummoner = await response.Content.ReadAsAsync<LSummoner>();
                summ.summoners.Add(new LSummoner(lSummoner.profileIconId, lSummoner.name, lSummoner.puuid, lSummoner.summonerLevel, lSummoner.revisionDate,
                    lSummoner.id, lSummoner.accountId));
            }
            else
            {
                response.EnsureSuccessStatusCode();
            }
        }
    }

    /// <summary>
    /// Get the ranked data of a summoner by the Encrypted SummonerID from the RiotGames API
    /// </summary>
    /// <param name="_rg"></param>
    /// <param name="summoner"></param>
    /// <param name="encryptedSummonerID"></param>
    /// <returns></returns>
    public static async Task getSummonerRankBySummonerID(Regions _rg, LSummonerRanked summonerRanked, string encryptedSummonerID)
    {
        using (HttpClient client = new HttpClient())
        {
            Region region = new Region();
            client.BaseAddress = new Uri("https://" + region.getRegionConnectionString(_rg));
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync($"{RANKED_API}{encryptedSummonerID}?api_key={API_KEY}");
            if (response.IsSuccessStatusCode)
            {
                LSummonerRanked lSummonerRanked = await response.Content.ReadAsAsync<LSummonerRanked>();
                summonerRanked.summonerName = lSummonerRanked.summonerName; summonerRanked.tier = lSummonerRanked.tier;
                summonerRanked.rank = lSummonerRanked.rank;
            }
            else
            {
                response.EnsureSuccessStatusCode();
            }
        }
    }

LSummoner 和 LSummonerRanked 对象都有 {get; set;} 公共数据类型的访问器。任何帮助都会很好,不要期待解决方案,只是朝着正确方向发展。我想尝试从这些错误中吸取教训。谢谢!

标签: c#wpf

解决方案


考虑到混合 UI 和工作线程的调用的性质,最好使用异步事件处理程序

private async void Window_Loaded(object sender, RoutedEventArgs e) {
    //On UI thread here...

    //On worker thread here (non-blocking)
    await APIConnect.getSummonerByName(Regions.NA, summoner, "Fusion Icee");

    //Back on UI Thread
    this.tbSummonerName.Text = summoner.name;
    this.tbSummonerLevel.Text = summoner.summonerLevel.ToString();

    var rHandler = new RankHandler();
    var rankedSummoner = new LSummonerRanked();

    //On worker thread (non-blocking)
    await APIConnect.getSummonerRankBySummonerID(Regions.NA, rankedSummoner, summoner.id);

    //Back on UI thread
    this.tbRankDivision.Text = rankedSummoner.tier + "" + rankedSummoner.rank;
    this.imgRankedIcon.Source = new BitmapImage(new Uri(rHandler.getRankedIcon(rankedSummoner.tier).ToString()));
}

查看评论以了解流程

参考Async/Await - 异步编程的最佳实践


推荐阅读