プリザンターのAPI連携をデスクトップアプリで使ってみた!

IISの石崎です。
以前にIISの田口が「プリザンターのAPI連携を試してみた!」と「プリザンターのAPI連携を試してみた!(実践編)」という記事を書いています。

今回は、APIで取得したデータを一覧表示するWindowsデスクトップアプリをC#で書いてみます。

完成イメージ

このようなデータが登録されていると
f:id:imageinformationsystem:20181015174844j:plain

このように一覧表示されます。
f:id:imageinformationsystem:20181015174909j:plain

画面上部の「タイトル」「説明」テキストボックスで取得するデータの条件を設定できます。

コード

コード全体はこのようになっています。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が最も得意とする領域です。今後もプリザンターとデスクトップアプリの連携の研究を進めて行くつもりです。デスクトップアプリとの連携に関心のある方、よかったらブログ上部の「+読者になる」をクリックをお願いします!

.NET Conf 2018 Tokyo, Japanで当社エンジニアが話しをしてきました

IIS技術広報チームです。
先日開催された .NET Conf 2018 Tokyo, Japan のUnconferenceでIISの石崎が登壇しました。

.NET Conf 2018 Tokyo, Japan」とは?
2018/9/12 - 9/14 に US で開催のイベント .NET Conf 2018 を受けて、その日本版となる .NET Conf 2018 Tokyo, Japan を 10/13 (土) に品川で開催します。

引用元: https://csugjp.connpass.com/event/100049/

Windowsデスクトップの最新アップデートなどをテーマに話をしました。
会場も盛り上がり、デスクトップアプリへの関心もまだまだあるようです。

デスクトップアプリの話題に盛り上がる会場の様子(若干の仕込みあり)
f:id:imageinformationsystem:20181015135441j:plain

IIS技術広報チームではメンバーの発表や登壇を推奨しています。発表や登壇に関心のある方、是非一度IISへ遊びにいらしてください。

技術書典5に一般参加してきました

IIS技術広報チームです。先日開催された技術書典5に一般参加してきました。

技術書典とは?

新しい技術に出会えるお祭りです。
技術書典は、いろんな技術の普及を手伝いたいとの想いではじまりました。
技術書を中心として出展者はノウハウを詰め込み、来場者はこの場にしかないおもしろい技術書をさがし求める、技術に関わる人のための場として『技術書典』を開催します。

引用元: https://techbookfest.org/

これまでは秋葉原での開催でしたが、非常に参加者が多く今回はより広いスペースのある池袋での開催となったようです。

注目度もどんどん上がっているようで、IISメンバー内でも今回は技術書典という面白そうなイベントが開催されるようだという話がされていました。技術サイドのメンバーとしてとてもうれしく思いました。

今回は出典サークルも多くなった上に会場も広くなったおかげで非常に会場内を回りやすくなっており、参加する前は2、3冊くらいと思っていたのに会場を出る際には10冊を超える「戦利品」を手にしていました。

           ◇        ◇        ◇

※以降の発言は個人の見解であり所属する組織を代表するものではありません。
参加してみて企業名を冠して活動している出典サークルが多数あることに気がつきました。前述のようにIIDメンバーでも技術書典に関心を持つメンバーも出てきましたし、いずれIISでも出典をする流れを作れると面白いだろうななどと夢見たりしています。
私たちと一緒に夢を見ても良いよという方、ぜひ一度IISへ遊びに来てください。

神保町 Unity & Unreal Engine 勉強会 #9

IIS石崎です。
IIS会議室を会場として「神保町 Unity & Unreal Engine 勉強会」を開催しました。

今回も写真のアングルを変えてみました
f:id:imageinformationsystem:20181009192724j:plain

神保町 Unity & Unreal Engine 勉強会

神保町 Unity & Unreal Engine 勉強会はプログラミングもくもく勉強会です。
主催メンバーは主にUnityおよびUnreal Engineを勉強しています。

基本は各自が自習・勉強し、わからないことがあったら周りの人に聞いてみたり、最近の関心ごとを話し合ったりする勉強会です。何か発表したい方は発表しても良い。そんな自由に勉強できる空間を目指しています。また、講義形式の勉強会ではありませんので、スライド作成や発表の練習の場としてもご活用していただきたいと考えています。

発表

今回は、参加されている方の人数もあり発表はなしでしたが、普段は多少はあります。
基本的には主催メンバーはまだ書籍の写経の段階ですが、Unity & Unreal Engineですから毎回動くものがあります。それを動かして見せるだけでも、動かして見せてもらうだけでも、進捗が目に見えてうれしいものです。

IISでは今のところはまだUnityやUnreal Engineを業務では扱っていませんが、今後必要にな技術だと考えています。今後も定期的に開催して行きますのでUnityやUnreal Engineをこれから頑張りたい方、一緒に学んで行きましょう。

今後の予定

次回以降はフォーマットを変えての開催を計画しています。日程や、もしかしたらお題にも変更があるかもしれません。 イベントは開催が決定したらconnpassサイトで告知・募集していますので是非チェックしてください。

設立1年目しめくくりパーティを開催しました

設立年のしめくくりと2年目への決起、そして新しい仲間と半年後から仲間になるメンバーの歓迎を目的に設立1年目しめくくりパーティが開催されました。イメージ情報システム株式会社(略称 IIS)は2017年10月にイメージ情報開発株式会社の子会社として設立し、今月で1周年を迎えました。

設立1年目しめくくりケーキ
f:id:imageinformationsystem:20181005223454j:plain

設立1年目しめくくり乾杯をする代表取締役
f:id:imageinformationsystem:20181005223507j:plain

この日のためにつくられた美味しくて強くなる1周年記念ノベルティ
f:id:imageinformationsystem:20181005223518j:plain

大盛況の会場の様子
f:id:imageinformationsystem:20181005223607j:plain f:id:imageinformationsystem:20181005223557j:plain f:id:imageinformationsystem:20181005223533j:plain f:id:imageinformationsystem:20181005223544j:plain

〆は当社伝統の五本締め
f:id:imageinformationsystem:20181005223645j:plain

これからのIIS

IISはこれから迎える設立2年目をさらなる飛躍の年にしていきます。これからのIISにもぜひご期待ください。

2018年09月 社内勉強会「合同勉強会」を開催しました

2018年09月の「合同勉強会」を開催しました。

「合同勉強会」 とは
株式会社フロッグポッドさんと当社イメージ情報システム株式会社の合同で行っている月次の社内IT勉強会です。
NDAの締結を前提とし、まだ世に出せないプロジェクトにかかわる内容なども話せる勉強会になっています。

今月の登壇

今月はフロッグポッドさんから2名とIISシステムエンジニア2名の4名が登壇しました。

4セッションとも非常にすばらしく、大変盛り上がりました。

勉強会のメリット

社内勉強会のメリット
社内勉強会には多くのメリットがあります。

  • 登壇者自身のスキルアップ
  • 参加者が幅広い知識が得られる
  • 別プロジェクトに携わっているメンバーとの交流・情報交換の機会となる
  • (技術的なこともそうでないことも)新しいチャレンジのきっかけとなる
  • コミュニティイベントより参加の敷居が低く新人なども参加しやすい

合同勉強会のメリット
合同勉強会にも多くのメリットがあります。

  • より緊張感をもって参加できる
  • 1社の文化に染まりきらない知識が得られる
  • コミュニティイベントよりも参加の敷居が低く新人なども参加しやすい

合同勉強会が気になった方へ

合同勉強会へ参加していただける企業様は常に歓迎です。メンバーの成長に関心のある方、是非一度IISへ遊びにいらしてください。

JXUG ハンズオンもくもく会に当社エンジニアがメンターとして参加しました

IIS石崎です。
先日開催されたJapan Xamarin Users Group (JXUG)のイベント「JXUG ハンズオンもくもく会」にIISの石崎がメンターとして参加しました。

JXUG ハンズオンもくもく会
これまで様々なXamarinのハンズオンが実施されてきました。
JXUGで開催されたハンズオンの中から参加者様が好きなものを選んでもくもくする会を開催いたします。

当日は多くの方が参加され、Xamarinの注目度の高さを実感しました。

IISではXamarinによるモバイルアプリ開発に力を入れています。Xamarinに関心のある方、ぜひ一度IISへ遊びに来てください。