- 投稿日:2022-01-25T23:33:44+09:00
アダプティブカードから送信された値をBot Frameworkで受け取る方法
前提 ①アダプティブカードの基本的な作成ができる方向けに記事を書きます。 以下の記事に基本的な作成方法はまとめていますので、良かったら参考にしてください。 https://qiita.com/rei_441/items/6c93a3cfe3c2b89521a9 ②Bot Frameworkを使用したことがある方向けになっています。 (いずれこちらもまとめて記事にしようと思っています。 早速やっていきます まず、クライアントはMicrosoftのTeamsを使用しています。 ユーザーからTeamsにてチャットが送信されると、TurnContextというオブジェクトがBot Framework側に送信されます。 この中にはM365のテナント情報やユーザーのIDなど、どのテナントの誰から送信されたメッセージなのかという情報を含んでいます。 実際にお見せしようと思ったのですが、隠さなければならない項目が多かったので割愛しますww また、この中にはturnContext.Activity.Textという値があり、ここにはユーザーから送られたメッセージのテキストを保持しています。 では、まずアダプティブカードに入力した値をBot Frameworkに送信するにはどうすればよいのかやっていきます。 アダプティブカードのAction.Submitを使用することでInput.Textなどに入力された値を送信することができます。 Inputに使用できるパーツには以下のものがあります。 では、前提に記載した記事の中で試作した以下のアダプティブカードを使用してやっていこうと思います。 この場合まず三つの入力項目があります。 上から ①名前入力する。 ②日付を入力する。 ③時間を入力する。 そして送信ボタンは"type"にAction.Submitを定義しています "actions": [ { "type": "Action.Submit", "title": "送信する" } ] 送信ボタンが押下されると入力された値がBot Frameworkへ送信されます。 受信した際にはturnContext.Activity.Valueの中に値が格納されるので、 自分はよく test.cs string testString = TurnContext.Activity.Value.ToString(); JObject details = JObject.Parse(testString); のようにして値を取得しています。 しかし、このままだと値を取得することはできません。 先ほどのアダプティブカードの入力項目それぞれにIdを設定する必要があり、 そのIdと入力値がKeyとValueの関係になり、turnContext.Activity.Valueに格納されています。 Idを振ったアダプティブカードのJsonがこちらになります。 sample.json { "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.3", "body": [ { "type": "TextBlock", "wrap": true, "text": "デモ版のアダプティブカードです。" }, { "type": "Input.Text", "placeholder": "名前を入力してください", "id": "inputName" }, { "type": "Input.Date", "id": "inputDate" }, { "type": "Input.Time", "id": "inputTime" } ], "actions": [ { "type": "Action.Submit", "title": "送信する" } ] } "body"の各項目にIdが定義されています。 このIdはユニークなものである必要があるので重複しないように気をつけてください。 アダプティブカードデザイナーではPreview modeを使用することで実際に送信される値を確認することができます。 送信ボタンを押下後 入力された値がIdと紐づいて送信されていることが確認できます。 これでアダプティブカード側の設定は終わったので、 BotFrameworkで受け取る処理を実装すれば完了です。 test2.cs //入力された値をJObjectへ詰める string testString = TurnContext.Activity.Value.ToString(); JObject details = JObject.Parse(testString); //各項目の値を取得する var inputName = details["inputName"]; var inputDate = details["inputDate"]; var inputTime = details["inputTime"]; これで値が取得できます。 まとめ アダプティブカードの値をBot Frameworkで取得するには ①アダプティブカードのInput項目にIdを定義する。 ②アダプティブカードにAction.submitのボタンを定義する。 ③Bot FrameworkにTurnContext.Activity.Valueの値を取得する処理を実装する。
- 投稿日:2022-01-25T20:27:15+09:00
enum のDisplayName が指定した文字列と一致するか調べる拡張メソッド
flags でないなら単純に指定されたenum値のDisplayName と文字列を比較すれば良いけどflags だと タイプ1,タイプ2、合成値 みたいな定義になってタイプ1かタイプ2のどちらかでよい場合、って言う比較があると便利かも、と思った こんな感じでどうだろう [Flags] public enum SampleTypes { [Display(Name = "flag none")] None = 0, [Display(Name = "flag 1")] Flag1 = 1, [Display(Name = "flag 2")] Flag2 = 2, [Display(Name = "flag 3")] Flag3 = 3, [Display(Name = "flag 4")] Flag4 = 4, [Display(Name = "flag all")] FlagAll = 7 } class Program { static void Main(string[] args) { var flag = SampleTypes.Flag3; // Your code here! System.Console.WriteLine(flag == SampleTypes.Flag3); System.Console.WriteLine(flag.DisplayNameMatches("flag all")); Console.ReadLine(); } } public static class EnumExtension { public static string DisplayName(this Enum value) { var enumType = value.GetType(); var memberInfo = enumType.GetMember(value.ToString()).First(); if (memberInfo == null || !memberInfo.CustomAttributes.Any()) { return value.ToString(); } var displayAttribute = memberInfo.GetCustomAttribute<DisplayAttribute>(); if (displayAttribute == null) { return value.ToString(); } return displayAttribute.Name ?? value.ToString(); } public static bool DisplayNameMatches(this Enum value, string name) { foreach(var e in Enum.GetValues(value.GetType())) { var sourceValue = (Enum)e; if(value.HasFlag((Enum)e)) { var displayName = DisplayName((Enum)e); if (displayName == name) { return true; } } } return false; } }
- 投稿日:2022-01-25T00:01:55+09:00
Dockerで.Net coreの開発環境を作成する方法
経緯 APIを c#で作成したいと思い立ち、フレームワークである.Net Coreを使用しAPI開発をしようと思ったのがやり始めたきっかけです。 現在、.Net Coreで開発しようとしていて、Dockerの開発環境を作成したいと考えている方の参考になればと思っています。 はじめに 今回の記事では、 .Net Coreの開発環境をDockerfileを記述し作成する。 リアルタイムでコードの変更が反映されるようにする。 Dbコンテナも作成し、接続する。 apiを叩いて動作確認。 おまけ. マルチステージビルドで軽量化イメージを作成する。 という流れで解説します。 Dockerfileの作成 今回は、便宜上ファイル名をDockerfile.developとさせていただきます。 また、自分のプロジェクト名はapiMyAppです。 FROM mcr.microsoft.com/dotnet/sdk:5.0 WORKDIR /src COPY apiMyApp.csproj ./ RUN dotnet restore COPY . . RUN dotnet dev-certs https --clean && dotnet dev-certs https -t docker-compose.ymlの作成 docker-compose.ymlファイルを作成します。 docker-compose.yml version: '3.8' services: app: container_name: net-app build: context: . dockerfile: Dockerfile.develop ports: - 5000:5000 - 5001:5001 networks: - net-net depends_on: - db volumes: - .:/src command: dotnet watch run db: container_name: net-db platform: linux/x86_64 image: mysql:5.7 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mysql MYSQL_USER: user MYSQL_PASSWORD: secret command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf networks: - net-net networks: net-net: driver: bridge .Net Coreのコンテナ名をnet-app、Databaseのコンテナ名をnet-dbと今回は設定しています。 ここで、ホットリロードの設定を行っているのが、net-appコンテナ内の docker-compose.yml volumes: - .:/src command: dotnet watch run の部分です。 volumesで、ローカルのコードと、コンテナ内のコードを同期させる。 commandsで、コンテナが立ち上がった際にホットリロードできるコマンドをうつ。 この二つ書いておけば、ホットリロードされます。 DBコンテナも記述していますが、おのおのコード内で接続できるよう記述してみてください。 詳しくは記述しませんが、.Net CorからDbコンテナに繋げる際、苦労した点としては、serverの部分がlocalhostでなくコンテナ名 を記述してやらないと繋がらなかったところです。(ここら辺はよくわかってない。) 後日更新予定
- 投稿日:2022-01-25T00:01:55+09:00
【Docker】.Net coreでAPI開発環境を作成する方法
経緯 APIを c#で作成したいと思い立ち、フレームワークである.Net Coreを使用しAPI開発をしようと思ったのがやり始めたきっかけです。 .Net CoreでAPI開発をしようとしていて、Dockerの開発環境を作成したいと考えている方の参考になればと思っています。 はじめに 今回の記事では、 .Net Coreの開発環境をDockerfileを記述し作成する。 リアルタイムでコードの変更が反映されるようにする。 Dbコンテナも作成し、接続する。 apiを叩いて動作確認。 おまけ. マルチステージビルドで軽量化イメージを作成する。 という流れで解説します。 Dockerfileの作成 今回は、便宜上ファイル名をDockerfile.developとさせていただきます。 また、自分のプロジェクト名はapiMyAppです。 FROM mcr.microsoft.com/dotnet/sdk:5.0 WORKDIR /src COPY apiMyApp.csproj ./ RUN dotnet restore COPY . . RUN dotnet dev-certs https --clean && dotnet dev-certs https -t ここでは、dotnetコマンドを使用するため、mcr.microsoft.com/dotnet/sdk:5.0 をベースイメージとします。 また、ディレクトリをsrcに移動し、ローカル内のcsprojファイルをコンテナ内にコピーします。 その後、csprojファイルをもとに、dotnet restoreコマンドで必要なパッケージをダウンロード。 その後、ローカルにあるプロジェクトファイル全てをコンテナ内に移動させます。 最後は、api通信を開発環境で行うためのコマンドを打ちます。(ニュアンスが違ってましたらすいません。) これで、Dockerfileの完成です。 次はdocker-compose.ymlファイルです。 docker-compose.ymlの作成 docker-compose.ymlファイルを作成します。 docker-compose.yml version: '3.8' services: app: container_name: net-app build: context: . dockerfile: Dockerfile.develop ports: - 5000:5000 - 5001:5001 networks: - net-net depends_on: - db volumes: - .:/src command: dotnet watch run db: container_name: net-db platform: linux/x86_64 image: mysql:5.7 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mysql MYSQL_USER: user MYSQL_PASSWORD: secret command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf networks: - net-net networks: net-net: driver: bridge .Net Coreのコンテナ名をnet-app、Databaseのコンテナ名をnet-dbと今回は設定しています。 ここで、ホットリロードの設定を行っているのが、net-appコンテナ内の docker-compose.yml volumes: - .:/src command: dotnet watch run の部分です。 volumesで、ローカルのコードと、コンテナ内のコードを同期させる。 commandsで、コンテナが立ち上がった際にホットリロードできるコマンドをうつ。 この二つ書いておけば、コンテナが立ち上がった際にプロジェクトが起動し、開発中はホットリロードされます。 DBコンテナも記述していますが、おのおのc#のコード内で接続できるよう記述してみてください。 詳しくは記述しませんが、.Net CorからDbコンテナに繋げる際、苦労した点としては、serverの部分がlocalhostでなくコンテナ名 を記述してやらないと繋がらなかったところです。(本題とは外れるので飛ばします。) DB接続できたら、api通信できているかどうか確認してみてください。 マルチステージビルド 最後に、本番環境ようの軽量イメージをマルチステージビルドを使用して作成します。 マルチステージビルドをすることによって、プロジェクトの規模にもよりますが、 1GB → 400MB ぐらいまで軽量化することができました。 以下、Dockerfileです。 FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY apiMyApp.csproj ./ RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT [ "dotnet", "apiMyApp.dll" ] 順番に説明すると、 AS baseの部分では、.net coreのアプリを実行できるイメージを取得しているステージです。 AS buildでは、プロジェクトをビルドするステージです。 最後に、AS finalでは、AS baseで作成した実行環境とAS buildで作成したビルドを使用してアプリを動かすステージです。 このようにステージを分けることでイメージの大きさを小さくし、本番環境むきのイメージを作成することができます。 最後に c#レベルのプレーンなプログラミング言語に触れた方が他の言語への移りが容易になるんじゃないかと思ってます。 参考
- 投稿日:2022-01-25T00:01:55+09:00
Dockerで.Net coreのAPI開発環境を作成する方法
経緯 APIを c#で作成したいと思い立ち、フレームワークである.Net Coreを使用しAPI開発をしようと思ったのがやり始めたきっかけです。 .Net CoreでAPI開発をしようとしていて、Dockerの開発環境を作成したいと考えている方の参考になればと思っています。 はじめに 今回の記事では、 .Net Coreの開発環境をDockerfileを記述し作成する。 リアルタイムでコードの変更が反映されるようにする。 Dbコンテナも作成し、接続する。 apiを叩いて動作確認。 おまけ. マルチステージビルドで軽量化イメージを作成する。 という流れで解説します。 Dockerfileの作成 今回は、便宜上ファイル名をDockerfile.developとさせていただきます。 また、自分のプロジェクト名はapiMyAppです。 FROM mcr.microsoft.com/dotnet/sdk:5.0 WORKDIR /src COPY apiMyApp.csproj ./ RUN dotnet restore COPY . . RUN dotnet dev-certs https --clean && dotnet dev-certs https -t ここでは、dotnetコマンドを使用するため、mcr.microsoft.com/dotnet/sdk:5.0 をベースイメージとします。 また、ディレクトリをsrcに移動し、ローカル内のcsprojファイルをコンテナ内にコピーします。 その後、csprojファイルをもとに、dotnet restoreコマンドで必要なパッケージをダウンロード。 その後、ローカルにあるプロジェクトファイル全てをコンテナ内に移動させます。 最後は、api通信を開発環境で行うためのコマンドを打ちます。(ニュアンスが違ってましたらすいません。) これで、Dockerfileの完成です。 次はdocker-compose.ymlファイルです。 docker-compose.ymlの作成 docker-compose.ymlファイルを作成します。 docker-compose.yml version: '3.8' services: app: container_name: net-app build: context: . dockerfile: Dockerfile.develop ports: - 5000:5000 - 5001:5001 networks: - net-net depends_on: - db volumes: - .:/src command: dotnet watch run db: container_name: net-db platform: linux/x86_64 image: mysql:5.7 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mysql MYSQL_USER: user MYSQL_PASSWORD: secret command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf networks: - net-net networks: net-net: driver: bridge .Net Coreのコンテナ名をnet-app、Databaseのコンテナ名をnet-dbと今回は設定しています。 ここで、ホットリロードの設定を行っているのが、net-appコンテナ内の docker-compose.yml volumes: - .:/src command: dotnet watch run の部分です。 volumesで、ローカルのコードと、コンテナ内のコードを同期させる。 commandsで、コンテナが立ち上がった際にホットリロードできるコマンドをうつ。 この二つ書いておけば、コンテナが立ち上がった際にプロジェクトが起動し、開発中はホットリロードされます。 DBコンテナも記述していますが、おのおのc#のコード内で接続できるよう記述してみてください。 詳しくは記述しませんが、.Net CorからDbコンテナに繋げる際、苦労した点としては、serverの部分がlocalhostでなくコンテナ名 を記述してやらないと繋がらなかったところです。(本題とは外れるので飛ばします。) DB接続できたら、api通信できているかどうか確認してみてください。 マルチステージビルド 最後に、本番環境ようの軽量イメージをマルチステージビルドを使用して作成します。 マルチステージビルドをすることによって、プロジェクトの規模にもよりますが、 1GB → 400MB ぐらいまで軽量化することができました。 以下、Dockerfileです。 FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY apiMyApp.csproj ./ RUN dotnet restore COPY . . RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT [ "dotnet", "apiMyApp.dll" ] 順番に説明すると、 AS baseの部分では、.net coreのアプリを実行できるイメージを取得しているステージです。 AS buildでは、プロジェクトをビルドするステージです。 最後に、AS finalでは、AS baseで作成した実行環境とAS buildで作成したビルドを使用してアプリを動かすステージです。 このようにステージを分けることでイメージの大きさを小さくし、本番環境むきのイメージを作成することができます。 最後に c#レベルのプレーンなプログラミング言語に触れた方が他の言語への移りが容易になるんじゃないかと思ってます。 参考