SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ASP.NET Core Blazorチュートリアル

ASP.NET Coreのホストでブラウザの制限を回避

ASP.NET Core Blazorチュートリアル 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

セレクトボックスの表示

 まずは、天気予報の地域を選択するセレクトボックスを表示する処理です。

CSVファイルの準備

 気象庁の天気予報は、「予報区」と呼ばれる、全国、地方、府県の区域毎に発表されます(なお、府県といっても、都道府県単位というわけでなく、北海道などは複数に分割されています)。今回のアプリでは、府県予報区をセレクトボックスで選択できるようにしています。

 府県区分の名称やそのコード番号などの情報は、気象庁の資料ページで公開されています。今回は、公開されている資料から、名称とコード番号をカンマ区切りにしたCSVファイルを自分で作成して利用します。1行は、コード番号、府県名という並びにし、日本語の文字コードは、UTF-8としました。

[リスト1]code.csv
011000,宗谷地方
(略)
130000,東京都
(略)
474000,八重山地方

府県コードクラス

 このCSVファイルのデータをC#で利用するために、データの入れ物となるモデルクラスを定義しておきましょう。コードと名称のプロパティがあるだけの単純なクラスです。このクラスは、クライアント、サーバーの両方のプロジェクトで共用しますので、~.Sharedの名前のプロジェクトに作成します。

[リスト2]FukenCode.cs
// 府県予報区コードクラス
public class FukenCode
{
    public string Code { get; set; } // 府県予報区コード
    public string Name { get; set; } // 府県予報区名
}

府県コードを返すWebAPI

 次に、ASP.NET Coreでのサーバー機能を使って、この府県コードをJSONデータで返すWebAPIを作成します。Blazor WebAssemblyのテンプレートで生成される、ASP.NET Coreサーバープロジェクトは、ASP.NET Core Web APIベースのテンプレートになっているため、このような処理も、少しのコードを追加するだけで済みます。

ASP.NET Core Web API

 「ASP.NET Core Web API」は、ブラウザなどのクライアントに、RESTfulなHTTPサービス(Web API)を提供するためのフレームワークです。REST(REpresentational State Transfer)は、分散型システムにおけるソフトウェア連携の設計スタイルのことで、2000年に提唱されたものです。RESTには、HTTPベースのプロトコルであること、データの取得や更新などの操作は、すべてHTTPメソッド(GET、POST、PUT、DELETE)を利用すること、などの原則があります。このようなRESTの原則に基づいて設計されたものを、「RESTfulな○○」と呼びます。

 また、ASP.NET Core Web APIフレームワークは、MVC(Model-View-Controller、モデル・ビュー・コントローラ)モデルをベースにしています。MVCとは、データやその処理を担う「Model」、UI出力処理の「View」、そして入力をモデルに伝える「Controller」という3つにアプリケーションを分離する設計モデルです。

 Blazor用のテンプレートで生成されたサーバープロジェクトには、Controllersフォルダに、Controllerとなるクラスが生成されています。また、Pagesフォルダには、Viewにあたるファイルがあります。なお、Modelにあたるクラスは独立して生成されませんので、必要に応じて自分で追加することになります。

コントローラーの追加

 それでは、先ほどのCSVファイルを使って、府県予報区コードのJSON形式データを返すAPIを作成してみます。定型的な処理は、ほとんどテンプレートに記述されていますので、実際に追加するコードは多くありません。

 ソリューションエクスプローラーで、プロジェクト名.ServerにあるControllersフォルダを選択して、右クリックして表示されるメニューから、[追加]-[新しい項目]を選びます。そして次の画面では、「APIコントローラー-空」を選択し、ファイル名(ここでは、JmaController.cs)を入力して作成します。クラス名には、Controllerを付けるのが慣例です。

 この操作で追加されるファイルは、ControllerBaseクラスを継承した、Web APIのコントローラークラス(JmaControllerクラス)となります。生成されたクラス内には何も定義されていないので、次のようなメソッド(ここではGetCodeメソッド)を追加します。

[リスト3]JmaController.cs
namespace BlazorTutorial2.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")] // (1)
    public class JmaController : ControllerBase
    {
        [Route("code")]
        public IEnumerable<FukenCode> GetCode()
        {
            // CSVの読み込み(2)
            using var sr = new StreamReader(@"code.csv");
            while (!sr.EndOfStream)
            {
                // CSVファイルの一行から府県コードオブジェクトを作成する(3)
                var ary = sr.ReadLine().Split(',');
                yield return new FukenCode { Code = ary[0], Name = ary[1] };
            }
        }
     }
}

 なお、コントローラーとなるクラスには、次の3つが備わっている必要があります。

  1. [ApiController] 属性を付加する
  2. ControllerBaseクラスを継承する
  3. APIとなるメソッドに、ルーティングを示す属性を追加する

 1と2は、テンプレートで生成されていますので、APIとなるメソッドと、3の属性を追加するだけです。ここでは、GetCodeメソッドを追加しています。

ルーティングを示す属性

 ルーティング属性は、クライアントがリクエストするURLと、サーバーでの処理を関連づける属性です。ルーティング属性は、クラス定義の前にも、メソッドの前にも付加することができます。クラスの前に付加すると、すべてのメソッドに共通のルーティングが追加されることになります。

 JmaControllerクラスの定義の前には、[Route("api/[controller]")]が追加されています(1)。[controller]は、トークンの置換と呼ばれる機能です。この[controller]は、コントローラー名(クラス名からControllerを除いたもの)に置換されます。ここでは、各APIのリクエストURLは、「ルート/api/jma/~」ということになります。

 また、追加したGetCodeメソッドには、[Route("code")]と記述していますので、このメソッドのリクエストURLは、「ルート/api/jma/code」ということになります。

 なお、直接"code"のような文字を書く代わりに、ここでもトークンの置換が使えます。トークンとして[action]と指定すれば、メソッド名がそのままルーティングに使われます。[action]を使って、同じ定義とするには、次のように記述します。

[Route([action])]
public IEnumerable<FukenCode> Code()

GetCodeメソッドの処理

 GetCodeメソッドでは、先のCSVファイルを読み込み、IEnumerator<FukenCode>型のオブジェクトを返しています。

 CSVファイルのようなテキストファイルを読み込む方法は、いくつかありますが、今回は、StreamReaderクラスを利用しました(2)。StreamReaderクラスのコンストラクタで、CSVファイルを指定しています。このCSVファイルは、サーバープロジェクトの直下に配置しておきます。

 StreamReaderクラスのReadLineメソッドで1行を文字列として読み取り、Splitメソッドで、配列に分割しています(3)。そして配列から、府県コードオブジェクトを生成しています。なお、yield returnを用いているため、別途コレクションオブジェクトなどに保持して、最後にそのオブジェクト返す処理は必要ありません。

 ただし、yield returnは、try~catch構文の中では使用できないため、ファイルの読み込みエラーなどの例外処理を行いたい場合は、yield returnを使わずに、最後にreturnするコードのほうがシンプルになるでしょう。

 戻り値のIEnumerator<FukenCode>型のオブジェクトからJSON形式への変換は、フレームワーク内で行われます。そのため、これだけのコードで、JSON形式のデータを返すAPIとなります。

 ここまでのソースをビルドすると、「https://localhost:44336/api/jma/code」というURLで、次のようなJSONデータを参照することができます。なお、FukenCodeクラスの定義では、プロパティ名の1文字目は大文字でしたが、JSONデータに変換されるとプロパティはすべて小文字になります。

[
 {
 "code": "011000",
 "name": "宗谷地方"
 },
 ...
]

セレクトボックスの表示処理

 それでは、このJSONデータを読み込み、セレクトボックスとして表示するページを作ってみましょう。といっても、テンプレートで自動生成された、FetchData.razorとほとんど同じ形になります。

[リスト4]Jma.razor
@page "/tenki"
@using BlazorTutorial2.Shared
@inject HttpClient Http

@if (codes == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <select @bind="selectCode" class="form-control">
        @foreach (var c in codes)
        {
            <option value="@c.Code">@c.Name</option>
        }
    </select>
}

@code {
    // 府県コードオブジェクトの配列
    private FukenCode[] codes;

    // 選択された府県コード
    private string selectCode { get; set; } = "130000";

    protected override async Task OnInitializedAsync()
    {
        // JSONデータを府県コードオブジェクトの配列に変換する
        codes = await Http.GetFromJsonAsync<FukenCode[]>("api/jma/code");
    }
}

 最初に、@usingディレクティブにて、共有するクラスの名前空間をインポートしておきます。

 JSONデータの読み込みは、最初にページが表示された際に非同期で呼び出される、OnInitializedAsyncメソッドのなかで行います。Http.GetFromJsonAsyncメソッドで、先ほど作成したWeb APIのURLを指定します。これで、フィールドの変数codesに、府県コードオブジェクトの配列が格納されます。

 HTML部分では、セレクトボックスを作成する<select>タグ内に、変数codesをforeachループで参照し、<option>タグで要素を追加しています。

 また、@bindディレクティブで、プロパティのselectCodeを指定しています。selectCodeは、双方向バインディングとなりますので、selectCodeの初期値と合致する、<option>要素が最初に表示されます。初期値は、東京のコード番号(130000)としていますので、セレクトボックスには、東京が表示されるはずです。

 selectCodeプロパティには、セレクトボックスの値を変更するたびに、選択した<option>タグのvalue属性の値がセットされます。

セレクトボックスの表示
セレクトボックスの表示

最後に

 今回は、天気予報アプリの前半部分を解説しました。次回は、天気予報が書かれたXMLファイルをダウンロードし、そのXMLをXSLスタイルシートを用いてページを表示する部分を解説することにします。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ASP.NET Core Blazorチュートリアル連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/14119 2021/05/28 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング