【C#】WindowsForms ネットワークから情報を取得(Text.Jsonの場合)

MicroSoftが開発したJsonのユーリィリティを使って分析するようにしました

対応バージョン

.NET6以降

その他のターゲット フレームワークの場合は、System.Text.Json NuGet パッケージをインストールします。 このパッケージで以下がサポートされます。

  • .NET Standard 2.0 以降のバージョン
  • .NET Framework 4.7.2 以降のバージョン
  • .NET Core 2.0、2.1、および 2.2

サンプルコード

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Windows.Forms;

namespace WeatherCheckerTextJson
{
    public partial class Form1 : Form
    {
        private readonly Dictionary<string, string> cityCodes = new Dictionary<string, string>
        {
            ["東京都"] = "3",
            ["大阪府"] = "1",
            ["愛知県"] = "2",
            ["福岡県"] = "10"
        };

        public Form1()
        {
            InitializeComponent();
            InitializeCityComboBox();
        }

        private void InitializeCityComboBox()
        {
            foreach (string cityName in cityCodes.Keys)
            {
                areaBox.Items.Add(cityName);
            }
        }

        private async void CitySelected(object sender, EventArgs e)
        {
            if (cityCodes.TryGetValue(areaBox.Text, out string cityCode))
            {
                string url = $"データがあるURL={cityCode}";

                using HttpClient client = new HttpClient();
                string json = await client.GetStringAsync(url);

                var options = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };

                var weatherInfo = JsonSerializer.Deserialize<WeatherInfo>(json, options);

                weatherIcon.ImageLocation = weatherInfo.Url;
            }
        }

        private void ExitMenuClicked(object sender, EventArgs e)
        {
            Close();
        }
    }

    public class Location
    {
        public string Longitude { get; set; }
        public string Latitude { get; set; }
    }

    public class WeatherInfo
    {
        public string City { get; set; }
        public string Weather { get; set; }
        public Location Location { get; set; }
        public string Percent { get; set; }
        public string Humidity { get; set; }
        public string Temperature { get; set; }
        public string Wind { get; set; }
        public string Pressure { get; set; }
        public string Url { get; set; }
    }
}

リファクタリングをしてみる

コードの可読性を向上させ、重複を減らし、一貫性を持たせました。また、非同期コードの実行についても適切な方法で処理しました

このリファクタリング版では、主な変更点は次のとおりです

  1. HttpClientJsonSerializerOptions をクラスレベルのフィールドとして初期化し、非同期メソッド内で再作成する必要がなくなりました
  2. GetWeatherInfoAsync メソッドを作成して、天気情報を非同期に取得するコードを分離しました
  3. 不要な using ステートメントは削除しました
  4. メソッドとクラスの名前をわかりやすくし、一貫性を持たせました
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WeatherCheckerTextJson
{
    public partial class Form1 : Form
    {
        private readonly Dictionary<string, string> cityCodes = new Dictionary<string, string>
        {
            ["東京都"] = "3",
            ["大阪府"] = "1",
            ["愛知県"] = "2",
            ["福岡県"] = "10"
        };

        private readonly HttpClient httpClient = new HttpClient();
        private readonly JsonSerializerOptions jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };

        public Form1()
        {
            InitializeComponent();
            InitializeCityComboBox();
        }

        private void InitializeCityComboBox()
        {
            foreach (string cityName in cityCodes.Keys)
            {
                areaBox.Items.Add(cityName);
            }
        }

        private async void CitySelected(object sender, EventArgs e)
        {
            if (cityCodes.TryGetValue(areaBox.Text, out string cityCode))
            {
                WeatherInfo weatherInfo = await GetWeatherInfoAsync(cityCode);
                weatherIcon.ImageLocation = weatherInfo.Url;
            }
        }

        private async Task<WeatherInfo> GetWeatherInfoAsync(string cityCode)
        {
            string url = $"データがあるURL={cityCode}";
            string json = await httpClient.GetStringAsync(url);
            return JsonSerializer.Deserialize<WeatherInfo>(json, jsonOptions);
        }

        private void ExitMenuClicked(object sender, EventArgs e)
        {
            Close();
        }
    }

    public class Location
    {
        public string Longitude { get; set; }
        public string Latitude { get; set; }
    }

    public class WeatherInfo
    {
        public string City { get; set; }
        public string Weather { get; set; }
        public Location Location { get; set; }
        public string Percent { get; set; }
        public string Humidity { get; set; }
        public string Temperature { get; set; }
        public string Wind { get; set; }
        public string Pressure { get; set; }
        public string Url { get; set; }
    }
}

このコードは、C#言語を使用して作成された天気情報を取得して表示するためのWindows Formsアプリケーションです。以下でコードの概要と主要な部分を説明します。

  1. 名前空間とクラスの定義: コードの最初には、WeatherCheckerTextJsonという名前空間が定義されており、その中にForm1というクラスが含まれています。Form1クラスはWindows Formsアプリケーションのメインフォームを表します。
  2. 都市コードの辞書とHttpClientの設定: Form1クラス内には、都市名をキーとして対応する都市コードを保持するcityCodesという辞書が定義されています。また、HTTP通信を行うためのHttpClientインスタンスも定義されています。
  3. JsonSerializerOptionsの設定: Jsonデータのシリアライズやデシリアライズに関するオプションを設定するために、JsonSerializerOptionsが定義されています。ここでは、プロパティ名の命名規則をキャメルケースにする設定が行われています。
  4. コンストラクタとフォームの初期化: Form1クラスのコンストラクタ内で、フォームの初期化と都市コンボボックスの設定が行われています。InitializeComponent()は、デザイナで作成されたコントロールの初期化を行います。
  5. 都市コンボボックスの初期化: InitializeCityComboBox()メソッドでは、都市コードの辞書のキー(都市名)を取り出し、それらをコンボボックスに追加しています。
  6. 都市選択時のイベント処理: 都市コンボボックスで都市が選択された際に呼び出されるCitySelectedメソッドでは、選択された都市のコードを元に天気情報を非同期で取得し、その情報を表示します。
  7. 天気情報取得の非同期メソッド: GetWeatherInfoAsyncメソッドは、指定された都市コードを使用して天気情報を取得します。HttpClientを使用して指定されたURLからJsonデータを取得し、それをデシリアライズしてWeatherInfoクラスのインスタンスとして返します。
  8. WeatherInfoクラスとLocationクラスの定義: WeatherInfoクラスは天気情報を表すクラスで、Locationクラスは位置情報を表すクラスです。これらのクラスのプロパティは、Jsonデータとのマッピングを行うために使用されます。
  9. 終了メニューのクリックイベント: 終了メニューがクリックされたときに呼び出されるExitMenuClickedメソッドでは、アプリケーションを終了します。

このアプリケーションは、Windows Formsを使用してGUIを構築し、HttpClientを使用して外部APIから天気情報を取得し、取得した情報をフォーム上に表示するためのものです。また、Jsonデータのシリアライズとデシリアライズにも関連する設定が行われています。

Jsonフォーマットからクラスを作成するツール