プリザンターのAPI連携をデスクトップアプリで使ってみた!
IISの石崎です。
以前にIISの田口が「プリザンターのAPI連携を試してみた!」と「プリザンターのAPI連携を試してみた!(実践編)」という記事を書いています。
今回は、APIで取得したデータを一覧表示するWindowsデスクトップアプリをC#で書いてみます。
完成イメージ
このようなデータが登録されていると
このように一覧表示されます。
画面上部の「タイトル」「説明」テキストボックスで取得するデータの条件を設定できます。
コード
コード全体はこのようになっています。jsonを扱うためにNuGetでJson.NETをインストールしています。
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Margin="5"> <TextBlock Text="タイトル" Margin="5,0" VerticalAlignment="Center"/> <TextBox Width="100" x:Name="title"/> <TextBlock Text="説明" Margin="5,0" VerticalAlignment="Center"/> <TextBox Width="100" x:Name="body"/> </StackPanel> <Button Content=" Item取得 " Margin="5,0" HorizontalAlignment="Right" Click="Button_Click"/> <DataGrid ItemsSource="{Binding}" Grid.Row="1" IsReadOnly="True" x:Name="dataGrid"> </DataGrid> </Grid> </Window>
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Windows; namespace WpfApp1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private async void Button_Click(object sender, RoutedEventArgs e) { // Apiキー、HttpClient の準備 var apiKey = "取得したAPIキー"; var httpClient = new HttpClient(); // 取得条件のセット var requestData = new ApiRequest(); requestData.View.ColumnFilterHash.Add("Title", title.Text); requestData.View.ColumnFilterHash.Add("Body", body.Text); // API 呼び出し Item を取得 var apiClient = new ApiClient(); var apiResponse = await apiClient.GetItemsAsync(httpClient, apiKey, "http://localhost:1759/", "Api_Items", 取得するテーブルのID, "get", requestData); // 取得結果の表示 dataGrid.DataContext = apiResponse.Response.Data; } } public class ApiClient { public async Task<ApiResponse> GetItemsAsync(HttpClient httpClient, string apiKey, string baseUrl, string apiName, long id, string apiMethod, ApiRequest requestData) { requestData.ApiKey = apiKey; var json = JsonConvert.SerializeObject(requestData); var content = new StringContent(json, Encoding.UTF8, "application/x-www-form-urlencoded"); var response = await httpClient.PostAsync($"{baseUrl}/{apiName}/{id}/{apiMethod}", content); var responseContentString = await response?.Content?.ReadAsStringAsync(); var responseContent = JsonConvert.DeserializeObject<ApiResponse>(responseContentString); return responseContent; } } public class ApiRequest { public string ApiKey { get; set; } public long Offset { get; set; } public View View { get; } = new View(); } public class View { public Dictionary<string, string> ColumnFilterHash { get; } = new Dictionary<string, string>(); } public class ApiResponse { public decimal? Id { get; set; } public decimal? StatusCode { get; set; } public string Message { get; set; } public Response Response { get; set; } } public class Response { public decimal? Offset { get; set; } public decimal? PageSize { get; set; } public decimal? TotalCount { get; set; } public Item[] Data { get; set; } } public class Item { public DateTimeOffset? UpdatedTime { get; set; } public long? ResultId { get; set; } public long? IssueId { get; set; } public long? Ver { get; set; } public string Title { get; set; } public string Body { get; set; } public long? Status { get; set; } public long? Manager { get; set; } public long? Owner { get; set; } public string ClassA { get; set; } public string ClassB { get; set; } public decimal? NumA { get; set; } public decimal? NumB { get; set; } public DateTimeOffset? DateA { get; set; } public DateTimeOffset? DateB { get; set; } public string DescriptionA { get; set; } public string DescriptionB { get; set; } public bool? CheckA { get; set; } public bool? CheckB { get; set; } public decimal? Updator { get; set; } public string ItemTitle { get; set; } } }
軽く解説
・メインの処理
メインの処理はMainWindowのButton_Clickメソッドです。取得条件(変数名: requestData)を構築して、API呼び出し処理(クラス名: ApiClient)でAPIを呼び出しています。取得結果は、DataGridへセットし画面表示しています。
// Apiキー、HttpClient の準備 var apiKey = "取得したAPIキー"; var httpClient = new HttpClient(); // 取得条件のセット var requestData = new ApiRequest(); requestData.View.ColumnFilterHash.Add("Title", title.Text); requestData.View.ColumnFilterHash.Add("Body", body.Text); // API 呼び出し Item を取得 var apiClient = new ApiClient(); var apiResponse = await apiClient.GetItemsAsync(httpClient, apiKey, "http://localhost:1759/", "Api_Items", 取得するテーブルのID, "get", requestData); // 取得結果の表示 dataGrid.DataContext = apiResponse.Response.Data;
・API呼び出し処理
APIを呼ぶ手続きをApiClientクラスにまとめています。将来他のAPIにも対応する事を見越して一旦、リソース名("Api_Items")やメソッド名("get")などを外から与えられる形にしています。別途リソース名のセットなどもまとめたファサードクラスを作っても良いかもしれません。
public class ApiClient { public async Task<ApiResponse> GetItemsAsync(HttpClient httpClient, string apiKey, string baseUrl, string apiName, long id, string apiMethod, ApiRequest requestData) { requestData.ApiKey = apiKey; var json = JsonConvert.SerializeObject(requestData); var content = new StringContent(json, Encoding.UTF8, "application/x-www-form-urlencoded"); var response = await httpClient.PostAsync($"{baseUrl}/{apiName}/{id}/{apiMethod}", content); var responseContentString = await response?.Content?.ReadAsStringAsync(); var responseContent = JsonConvert.DeserializeObject<ApiResponse>(responseContentString); return responseContent; } }
・POCO
残りのクラスは、APIで送受信するデータを持つPOCOです。jsonのデータを型のあるオブジェクトとして扱えるようにしています。型にうるさいC#の恩恵が受けられます。
public class ApiRequest { public string ApiKey { get; set; } public long Offset { get; set; } public View View { get; } = new View(); } public class View { public Dictionary<string, string> ColumnFilterHash { get; } = new Dictionary<string, string>(); } public class ApiResponse { public decimal? Id { get; set; } public decimal? StatusCode { get; set; } public string Message { get; set; } public Response Response { get; set; } } public class Response { public decimal? Offset { get; set; } public decimal? PageSize { get; set; } public decimal? TotalCount { get; set; } public Item[] Data { get; set; } } public class Item { public DateTimeOffset? UpdatedTime { get; set; } public long? ResultId { get; set; } public long? IssueId { get; set; } public long? Ver { get; set; } public string Title { get; set; } public string Body { get; set; } public long? Status { get; set; } public long? Manager { get; set; } public long? Owner { get; set; } public string ClassA { get; set; } public string ClassB { get; set; } public decimal? NumA { get; set; } public decimal? NumB { get; set; } public DateTimeOffset? DateA { get; set; } public DateTimeOffset? DateB { get; set; } public string DescriptionA { get; set; } public string DescriptionB { get; set; } public bool? CheckA { get; set; } public bool? CheckB { get; set; } public decimal? Updator { get; set; } public string ItemTitle { get; set; } }
最後に
C#によるデスクトップアプリ開発はIISが最も得意とする領域です。今後もプリザンターとデスクトップアプリの連携の研究を進めて行くつもりです。デスクトップアプリとの連携に関心のある方、よかったらブログ上部の「+読者になる」をクリックをお願いします!