Асинхронный вызов внешнего REST API из контроллера или представления? - PullRequest
0 голосов
/ 07 апреля 2020

Я слишком долго пытался обернуть голову вокруг этого. Это мой первый раз с C# и. NET, и кроме того, чтобы заниматься С ++ почти 15 лет go У меня нет опыта программирования. API-интерфейсы REST и асинхронность являются новыми концепциями для меня.

Я пытаюсь создать страницу с табло. NET MVC 5, состоящую из простой таблицы со строками, содержащими значения, полученные из базы данных MySQL , Каждая строка в таблице базы данных представляет уникального игрока вместе с его различными значениями статистики. Я создал модель для представления каждого игрока PlayerRow и передаю List<PlayerRow> своему представлению, где таблица генерируется с помощью @foreach (PlayerRow playerrow in Model).

Это мой текущий ActionResult PlayerList():

public class HomeController : Controller
{
    public ActionResult PlayerList()
    {
        List<PlayerRow> PlayerRows = new List<PlayerRow>();
        string constr = ConfigurationManager.AppSettings["MySQLConnStr"];
        using (MySqlConnection con = new MySqlConnection(constr))
        {
            string query = "SELECT * FROM `rankme`";
            using (MySqlCommand cmd = new MySqlCommand(query))
            {
                cmd.Connection = con;
                con.Open();
                using (MySqlDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        PlayerRows.Add(new PlayerRow
                        {
                            TableID = rdr["id"].ToString(),
                            LegacySteamID = rdr["steam"].ToString(),
                            Steam64 = ConvertToSteam64(rdr["steam"].ToString()),
                            Name = rdr["name"].ToString(),
                            IP = rdr["lastip"].ToString(),
                            Score = Convert.ToInt32(rdr["score"]),
                            etc etc...
                        });
                    }
                }
                con.Close();
            }
        }

        return View(PlayerRows);
    }
}

Соответствующий контент из моего PlayerList.cshtml:

        @foreach (PlayerRow playerrow in Model)
        {
        <tr>
            <th scope="row" class="avatar" id="@playerrow.Steam64"><img src="~/Content/placeholder.png"</th>
            <td><a href="http://steamcommunity.com/profiles/@playerrow.Steam64">@playerrow.Name</a></td>
            <td>@playerrow.Score</td>
            <td>@playerrow.Kills</td>
            <td>@playerrow.Deaths</td>
            <td>@playerrow.Assists</td>
            etc etc...
        </tr>
    }

Соединение MySQL работает очень хорошо, и таблица отображается так, как я хочу. (хотя пока не совсем отточено) Изображение моей текущей таблицы

Далее я хотел бы заменить аватар-заполнитель в каждой строке таблицы аватаром игроков, полученным через API Steam. , URL аватара каждого игрока можно получить из API Steam, вызвав https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=_API_KEY_&steamids=_STEAMID64_, который возвращает json ответ:

{
"response":{
  "players":[
     {
        "steamid":"EXAMPLE_STEAMID",
        "communityvisibilitystate":3,
        "profilestate":1,
        "personaname":"EXAMPLE_NAME",
        "commentpermission":1,
        "profileurl":"EXAMPLE_STEAM_PROFILE_URL",
        "avatar":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/EXAMPLE_AVATAR.jpg",
        "avatarmedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/81/EXAMPLE_AVATAR_medium.jpg",
        "avatarfull":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/EXAMPLE_AVATAR_full.jpg",
        "lastlogoff":1586222967,
        "personastate":0,
        "realname":"EXAMPLE_REALNAME",
        "primaryclanid":"103582",
        "timecreated":1070200624,
        "personastateflags":0,
        "loccountrycode":"US"
     }
  ]

Так что я предполагаю, что мне нужно сделать запрос, используя HttpClient() и ожидая ответ. Вот где я заблудился, потому что не могу дождаться ответа вне asyn c метода. Может быть, использование AJAX (которое я никогда не использовал) было бы более уместным?

Могу ли я создать asyn c метод для использования API Steam? Когда и откуда должен вызываться этот метод?

1 Ответ

1 голос
/ 07 апреля 2020

Для вызова асинхронного c метода из контроллера вы можете просто изменить свою подпись на

public async Task<IActionResult> PlayerList(CancellationToken cancellationToken)

Отсюда вы сможете вызывать любой async метод, который вам нравится.

Я действительно не знаю Steam API, поэтому, если вы собираетесь делать много сетевых вызовов, лучше сделать это на стороне браузера / Javascript (ленивый загрузка аватаров при прокрутке браузера).

...