web-dev-qa-db-ja.com

アダプティブカードデザイナーを使用し、サンプル値をC#の実際の値に置き換えます

目標

Adaptive Cards Designer を使用してアダプティブカードのデザインを作成(および編集)し、ボットで使用します。

手順

1) Designer にサンプル値を使用してアダプティブカードを作成し、そのJSON表現をコピーしました。例えば:

_{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "FactSet",
      "id": "myFactSet",
      "facts": [
        {
          "title": "Name:",
          "value": "John Doe"
        }
      ]
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0"
 }
_

2)次に、このカードのデザインをC#ボットフレームワークボットで使用します。このJSONを自分のプロジェクトに入れました。このプロジェクトには、AdaptiveCards v1.1.0 nugetパッケージが含まれています。

3)次のコード行を使用して、カードJSONを解析してAdaptiveCardsライブラリクラスに入れます。

_var card = AdaptiveCard.FromJson(card).Card;
_

4)ユーザーにカードを送信する前に、サンプルデータを置き換えて、実際の値をカードに入力する必要があります。

質問

  1. _"John Doe"_を実際のユーザー名に置き換えるにはどうすればよいですか?最も簡単なアプローチは何ですか? (IDでAdaptiveElementを取得するための拡張メソッドをすでに作成しているので、その値を簡単に変更できます。しかし、より簡単な方法があるかどうか教えてください)

  2. そして、どのようにして既存のAdaptiveElementを複製し、それに他の値を入れますか?たとえば、既存のFactSetをすべて同じスタイルでコピーして、カードに別のmyFactSetを追加したい場合はどうすればよいですか? AdaptiveElementにはClone()メソッドがありません。

他のソリューションが適合しない理由

C#で書いてください

カードのデザインをデザイナーで簡単に編集できるようにしたいのですが、C#コードでカード全体を書き換えた場合、カードのデザインが変更されるたびにカードに変更を加える必要があり、表示されません。デザイナーでの結果。

JavaScriptでそれを行います

私はそれがJavaScriptで簡単にできることを理解していますが、ボットでC#を使用しています。

JSONを解析して操作する

また、カードをJsonObjectに解析してJsonObjectsを直接処理し、それらを複製し、プロパティを変更できることも理解していますが、

  1. 入力されていないため、IntelliSenseのサポートはなく、タイプミスをすることができます

  2. 指定されたIDを持つ要素を見つけるために、すべての要素を歩く必要があります(ちなみに、これを簡単に行う拡張メソッドはありますか?)

  3. JsonObjectを使用しても、AdaptiveCardsライブラリの必要性がなくなり、AdaptiveCard.FromJson(card)メソッドを呼び出す必要がなくなります(_Attachment.Content_をJsonObjectに設定しても機能しない場合があるため)理由)。

8
Artemious

私たち(アダプティブカードチーム)は特にこれに取り組んでいます! 詳細はGitHubに投稿 を参照してください。

.NETとJSで利用できるプロトタイプJSONテンプレートライブラリがあり、プロトタイプを試してみて、それがシナリオで機能するかどうかを検証してください。今すぐ始めたい場合は、GitHubでご連絡ください:)

1
Andrew Leader

JSONは単なる文字列であることを忘れないでください。あなたの問題はどちらも文字列操作で解決できると思います。

  1. "John Doe"を実際のユーザー名に置き換えるにはどうすればよいですか?最も簡単なアプローチは何ですか?

JSONの "John Doe"をC#オブジェクトに変換する前に置き換えることができます。

json = json.Replace("John Doe", userName);
var card = AdaptiveCard.FromJson(json).Card;
  1. そして、どのようにして既存のAdaptiveElementを複製し、それに他の値を入れますか?

C#でのディープコピーの問題は よく議論されています です。工夫を凝らすと、オブジェクトのディープコピーを作成でき、アダプティブカードの要素も同じです。任意のオブジェクトをコピーする手法を使用するか、アダプティブカードに合わせて特別に調整された関数を作成できます。アダプティブカードはすべてJSONに関するものであるため、要素をJSONに変換してから再び元に戻すことを検討してください。

var factSet = card.Body.First() as AdaptiveFactSet;
factSet = JsonConvert.DeserializeObject<AdaptiveFactSet>(JsonConvert.SerializeObject(factSet));
factSet.Facts.First().Value = userName;
card.Body.Add(factSet);

ただし、JSONから始めているので、ディープコピーについて心配する必要さえないかもしれません。たぶん、特定の要素のJSONをデザイナーから取得して、それを複数回逆シリアル化できます。

factSet1 = JsonConvert.DeserializeObject<AdaptiveFactSet>(factSetJson);
factSet2 = JsonConvert.DeserializeObject<AdaptiveFactSet>(factSetJson);

カードのデザインをデザイナーで簡単に編集できるようにしたいのですが、C#コードでカード全体を書き換えた場合、カードのデザインが変更されるたびにカードに変更を加える必要があり、表示されません。デザイナーでの結果。

カードがC#とJSONの両方で表されている場合は、デザイナーで小さな変更を加えて外観を確認し、それに応じてC#を変更することはそれほど難しくありません。カードのJSONを取得し、それを生成できるC#を自動的に作成できるツールがあれば、本当にクールだと思うなら、同意します:)

1
Kyle Delaney

解決策は、新機能 アダプティブカードでのデータバインディング(プレビュー) を使用することです。

これは、{name}などのプレースホルダーをサポートし、$dataを介したテンプレートとコンテンツの分割をサポートします。

  • バインディング構文は{で始まり、}で終わります。例:{myProperty}
  • サブオブジェクトにアクセスするためのドット表記
  • キーまたは配列の項目でプロパティを取得するインデクサー構文
  • 深い階層の優雅なnull処理
  • エスケープ構文のドキュメントは近日公開予定

注:「現在、デザイナーの外部でデータバインディングを使用するには、ソースからSDKをビルドする必要があります。」

(リンクはプレビュー中であり、URLは一般出荷開始後に変更される可能性があります。)

1

私はまだ新しいデータバインディング機能を試していないので、それが自分のニーズを完全に満たしているかどうかはわかりませんが、説明からは見えないのは、アダプティブカードノードのコピーです(アダプティブカードのアイテムの動的リスト用) )。

私はアダプティブカードv1を使用したため、アダプティブカードノードのクローンを作成し、データに応じて値を変更する必要がありました。 これは私のプロジェクトからのコードです

0
Artemious

RazorEngine を使用して、デザイナーから生成されたカードjsonをデータモデルオブジェクトに対して処理し、Razor変数を実際の値に置き換えます。次に、AdaptiveCard.FromJson()を使用してカードを再度解析し、簡単に添付できるAdaptiveCardを取得します。

私の実装は、AdaptiveCardの人々が構築しているテンプレートよりも古いため、最初に試してみるとよいかもしれませんが、一般に利用できるかどうか、またはプラットフォームサポートがどのようなものかはわかりません。私は、Razorがほとんどの場合非常にうまく機能することを発見しました。かなりの戦いでテストされたテンプレートライブラリ、特に置換トークンに中括弧を使用しないライブラリを構築することは、非常に簡単です。

プロセスの概要:

デザイナーのJson:

{
"type": "AdaptiveCard",
"body": [
    {
        "type": "TextBlock",
        "text": "Hi @Model.Username"
    }
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"

}

RazorEngineテンプレートを作成します。

var config = new TemplateServiceConfiguration() {
    EncodedStringFactory = new RawStringFactory() // This encodes values as plain strings, rather than HTML-encoded
};
var engine = RazorEngineService.Create(config);

モデルオブジェクトを作成します。

var modelObject = new object {
    Username = "Foo Barrington"
}

テンプレートを介してjsonを実行します。

json = engine.RunCompile(json, Guid.NewGuid().ToString(), null, modelObject);

JsonをAdaptiveCardインスタンスに解析します。

var parsedCard = AdaptiveCard.FromJson(json);
if (parsedCard.Warnings.Any()) {
    // handle parsing errors...
}
AdaptiveCard card = parsedCard.Card;

テンプレート化および解析されたカードを使用して添付ファイルを作成します。

var attachment = new Attachment(AdaptiveCard.ContentType, content: card);
0
EricRRichards