Quantcast
Channel: てすとぶろぐ
Viewing all 208 articles
Browse latest View live

Windows デスクトップアプリにおける Live API によるサインイン

$
0
0

OneNote API の公開に合わせて色々試してみようと思ったのですが、VB のサンプルがないとかデスクトップアプリ向けコードサンプルがない(もとにできるものはあるけど C#)というのもあって、移植がてらやってみました。

実際に VB 用に移植したサンプルはこちらからダウンロードできます。
Visual Studio 2013 for Windows を用いて作成した、デスクトップアプリ(WPF)のサンプルです。

今のところ、サインイン+アプリの権限許可の際にどうしても WebBrowser が必須になっています。ブラウザ使うなら自動操縦ができるかと思い、取得された HTML を調査したのですが、BODY の OnLoad イベント時に JavaScript で復号をかけているためなのか、HTML として読める形での取得ができずに操作対象のエレメント名を取得できない状態です。

この部分で何らかの対応が行えれば自動操縦も可能となるので、アクティビティ化とかできるんだけどなぁ、と思いつつもとりあえずは OneNote API をこれから色々触っていこうと思います。


OneNote API Console

$
0
0

MSDN の OneNote API を調べていると、REST API については簡易コンソールがサードパーティより提供されているのでそれを使って色々試せるとあります。現時点ではそのアドレスの記述が間違っているので、ちょっと注意が必要ですが、ここにリンクを張っておきます。

image

上記のような画面で色々試せるようになっています。初期表示されているのは、OneNote に新規ノートを作成して機能の説明となるものが色々記載された内容を投稿するというものです。

ここの記述を元にすれば、クライアントアプリから OneNote API を利用してスクラップしたりすることもやりやすくなると思いますので、これからちょっとずつ試していこうと思います。

OneNote API を利用した新規ノートの作成

$
0
0

前回と同様、クライアントアプリで OneNote REST API を利用して色々試しています。今回は新規にノートを作成するところをやってみました。

今回のサンプルもこちらにアップしてありますので参考にしてください。
前回のサンプルにコードを追加した形となっています。

前回までのソースで、REST API によりサインインを行いアクセス用のトークンの取得までできていました。今回はそのトークンを用いて、実際に OneDrive 上の OneNote に新規にノートを作成します。

   1:PrivateSub btnCreate_Click(sender AsObject, e As RoutedEventArgs)
   2:  
   3:'新規ノートの作成
   4:Dim req = WebRequest.Create("https://www.onenote.com/api/v1.0/pages")
   5:     req.Method = "POST"
   6:     req.ContentType = "text/html"
   7:     req.Headers.Add("Authorization", "Bearer " + Application.Current.Properties("access_token"))
   8:'POST する HTML
   9:Dim postHtml = "<!DOCTYPE html>" + vbNewLine +
  10:"<html>" + vbNewLine +
  11:"<head>" + vbNewLine +
  12:"<title>OneNote API を使った POST サンプル</title>" + vbNewLine +
  13:"<meta name=""created"" content=""2013-06-11T12:45:00.000-8:00""/>" + vbNewLine +
  14:"</head>" + vbNewLine +
  15:"<body>" + vbNewLine +
  16:"<p>これは REST API を利用したサンプルにより作成されました。</p>" + vbNewLine +
  17:"</body>" + vbNewLine +
  18:"</html>"
  19:'POST データの生成
  20:Dim enc = Text.UTF8Encoding.UTF8
  21:Dim postBytes = Text.Encoding.UTF8.GetBytes(postHtml)
  22:     req.ContentLength = postBytes.Length
  23:'POST データの書き込み
  24:     Using st = req.GetRequestStream
  25:         st.Write(postBytes, 0, postBytes.Length)
  26:End Using
  27:'結果の受信
  28:Dim resStrings = New Text.StringBuilder
  29:     Using res = req.GetResponse
  30:         Using sr = res.GetResponseStream
  31:             Using sRead = New IO.StreamReader(sr, enc)
  32:                 resStrings.Append(sRead.ReadToEnd)
  33:End Using
  34:End Using
  35:End Using
  36:  
  37:     MessageBox.Show(resStrings.ToString)
  38:  
  39:End Sub

今回追加したコードは上記の部分です。

OneNote に追加する部分は HTML にて作成し、アクセストークンをヘッダーに含ませた形で POST します。新規に作成する際に利用する HTML タグは次のものを利用しています。

  1. TITLE:ノートのタイトル部分に記載する文字です
  2. META:name="created"とし content="作成日時"とすることでノートの作成日時を指定できます
  3. BODY:ノート本体に記述する内容です。文字だけであれば今回のサンプルのようにしますが、通常の HTML のように画像を含ませたりすることも可能です。

このように POST データを生成し、API を呼び出すことで次のようなノートが作成されます。

image

ノートのタイトルや作成日時が、コードで記述した通りになっているのがわかるかと思います。

このような形で REST API を呼び出すことで、アプリから OneDrive 上の OneNote へデータを登録させることが可能です。

OneNote API で Web サイトのキャプチャを登録する

$
0
0

OneNote API を色々試しているシリーズ、今回は Web サイトのキャプチャを登録してみました。なお現在 OneNote API の制限として、「新規ノートの作成」のみが可能というのもありますので、色々試される場合は、OneDrive 上に作成されたノートを毎回削除する必要があります。

OneNote API チームの公式 Blog でも書かれていますが、将来的な対応ということでまずは新規作成のみに限りリリースを行ったとの事ですので、近いうちに編集も可能になるかと思います。

Web サイトのキャプチャ、と言われている方式は OneNote では複数の方法が用意されています。

  1. アドレスを指定して OneNote 側で参照を行いキャプチャ
  2. HTML 構造を添付しその結果からキャプチャ

上記の方法で使うシーンが異なるケースもあることはあるのですが、個人的にはアドレス指定がメインで HTML 構造を添付する方法はなかなか使われないというか、その場合は画像として添付する方式を利用するのではないかな、と思います。なお、アドレス指定でキャプチャできないケースというのは、会員制サイトなどの認証が絡むケースで OneNote 側から参照できないサイトの場合になります。

アドレスを指定して OneNote 側で参照してもらう場合のコードは次のようになります。

   1:Dim req = WebRequest.Create("https://www.onenote.com/api/v1.0/pages")
   2: req.Method = "POST"
   3: req.ContentType = "text/html"
   4: req.Headers.Add("Authorization", "Bearer " + Application.Current.Properties("access_token"))
   5:'POST する HTML
   6:Dim postHtml =  "<!DOCTYPE html>" + vbNewLine +
   7:"<html>" + vbNewLine +
   8:"<head>" + vbNewLine +
   9:"<title>OneNote API を使った Web サイトキャプチャ POST サンプル</title>" + vbNewLine +
  10:"</head>" + vbNewLine +
  11:"<body>" + vbNewLine +
  12:"<p>これは REST API を利用して Web サイトをキャプチャしたサンプルです。</p>" + vbNewLine +
  13:"<img data-render-src=""http://blogahf.blogspot.jp/"" width=""400"" height=""400""></img>" + vbNewLine +
  14:"</body>" + vbNewLine +
  15:"</html>" + vbNewLine 
  16:'POST データの生成
  17:Dim enc = Text.UTF8Encoding.UTF8
  18:Dim postBytes = Text.Encoding.UTF8.GetBytes(postHtml)
  19: req.ContentLength = postBytes.Length
  20:'POST データの書き込み
  21: Using st = req.GetRequestStream
  22:     st.Write(postBytes, 0, postBytes.Length)
  23:End Using
  24:'結果の受信
  25:Dim resStrings = New Text.StringBuilder
  26: Using res = req.GetResponse
  27:     Using sr = res.GetResponseStream
  28:         Using sRead = New IO.StreamReader(sr, enc)
  29:             resStrings.Append(sRead.ReadToEnd)
  30:End Using
  31:End Using
  32:End Using

前回のサンプルと殆ど変り映えがなく、違いがあるのは POST している HTML の部分だけです。アドレスを指定してキャプチャする場合、img タグを利用します。data-render-src 属性でキャプチャしたい Web サイトのアドレスを指定すれば、OneNote 側でキャプチャを行いその結果がノートに貼り付けられます。


image


このような感じでキャプチャが貼り付けられます。

「ASP.NET MVC5 実践プログラミング」(秀和システム)レビュー

$
0
0

Twitter で書籍レビューを募集していたので速攻応募させてもらったこの本。3500 円と標準的な技術書価格ですが、内容は価格以上の物でした。

ASP.NET MVC 5実践プログラミング(Amazon)

ASP.NET MVC 5 を主体に解説していますが、MVC ~ MVC 4 の話も途中で含まれており、過去 Ver では使える使えないという点も開設されているので、純粋に ASP.NET MVC で開発を行おうと思った方全員にお勧めできる内容となっています。環境の設定から、開発、単体テストに Azure 上での利用まで、まさに広く全般をカバーしていますので、この本一冊を手元に置いておけば、大抵の事は対応できるのではないでしょうか。

この書籍でありがたいのは、本の構成を大きく 3 つに分けられているところと感じます。導入、基本、応用と分けてありますので、自分の必要な個所を探しやすいです(通常であれば目次などから探すのが先ですが、大きく3つに分けられているので探す範囲が最初から狭められる)。

技術本としては必須のコードによる解説ですが、この書籍では非常に多くのサンプルが記載されています。ダウンロードも可能として頂けているので、本を読みながら実際のソースを触りやすい環境を提供してくれています。これは非常にありがたいです(自分が書籍書いた時は、サンプルソース用意していたけど、それを記載するのが・・・)

ASP.NET Identity といった最近の要素に対してもページを用意していたり、コードを書いてカスタマイズする部分の例も分かりやすかったり、jQuery や Bootstrap についても多くなく少なくもない、必要丁度な量で解説されていたりと非常に読みやすい、でもものすごく役に立つ内容であったと思います。

自分の場合、過去に MVC 3 で開発していたのですが、しばらくその世界から離れており MVC 5 に至っては一度も触っていなかったので、なかなか手出ししにくい状況だったのですが、この本を片手に振れていなかった時間を取り戻しに行きたいと思います。MSCC にも参加する事ですしw

と、これだけべた褒めといっていい感じの感想ですが、個人的に一つだけ「あー」と思った点が。

VB については全く出てこない

いや、今の世の中じゃ仕方ないですし、Razor を VB 構文で書いたりしたらそれはもう・・・なのでわかってはいますw

DataGridView サンプルソースの公開

$
0
0

この Blog で過去にがりがり書いていた、DataGridView で伝票レイアウトを実現するために色々やっていた件について、ありがたいことに今でも見てくれている方がいらっしゃいまして。

サンプルソースが見たいというご要望を頂きましたので、それを公開します。
(ただし DataGridView に関連する部分に限定しているのと、古いソースなので動作チェックしていないのは注意してください)

DL はこちらから。
(http://1drv.ms/1GbzBBB)

Azure 仮想マシンに接続できないプロバイダ

$
0
0

契約しているプロバイダによっては、昨今の事情もあり RDP で利用したいポートがブロックされている事もあります。有名なのはぷららで、他にも同様のネットワーク制限を行っているプロバイダが散見されています。

そのような場合、RDP で利用するポートを変更することで通信できるようになるかも知れません。

VM との RDP で利用するポートは VM のエンドポイントとして設定されています。

image

上の画面で「Remote Desktop」と書かれている行で、パブリックポートとプライベートポートの設定があります。プライベートポートは Azure 内部でロードバランサーから対象となる VM への通信先になり、パブリックポートが自分の PC からロードバランサーへと通信する際のポートとなります。

プロバイダによってブロックされている場合は、このパブリックポートを通信可能なポート番号にする必要があります(上の画面では 1001 に変更した)。

本来 1024 以前のポートは Welknown ポートとして「他で利用しているから勝手に使うな」という扱いなのですが、プロバイダでブロックされている状態でそんなことは知ったことではありません(

TCP で利用されているポート一覧など、検索すると資料がたくさん見つかりますので、その中からまだ使われてなさそうな番号を利用するとガードを抜けられる可能性は高いです。

image

もし既に RDP 接続用のファイルをポータルから落としている場合は、テキストエディタで rdp ファイルを開き、ポート番号を設定した値に書き換えることで接続できるようになります。

Azure Websites で WF サービス

$
0
0

多分できるだろうと思われていても、その使い道の少なさから試していなかった WF サービスを Azure Websites 上で試してみました。

WF サービスを Azure Websites にて利用するには、通常の Websites 用プロジェクトに参照設定の追加と、web.config の追記が必要です。

image

追加している参照設定の中で、System.Activity 関係と PresentationFramework が必要です。
ただ、永続化しないなら System.Activities.DurableInstancing は不要だと思われます。

image

そして WF サービスに必要なファイルは xamlx と web.config の二つだけ、というのも全く同じです。web.config に追記する内容も変わりありません。

image

system.servicemodel の部分が追加したブロックになります。この部分を追加してあげるだけで、xamlx は WF サービスとして Azure Websites 上で動作します。

image

初期設定のままですので、サービスの URL にアクセスすると上記のような説明が表示されます。

image

WCF テストクライアントで動作確認すると上記のようになります。
今回試しで作成したサービスは、単純に文字列を返却するだけのサービスですが、ちゃんと動作しているのが見えると思います。


ASP.NET WebForms なアプリでの国際化対応

$
0
0

元々 ASP.NET は WebForms だろうと MVC だろうと、基本的には同じ方法で国際化対応ができますが、MSCC 向けアプリを作っている時に、WebForms の国際化対応がうまく行かなかったので忘れないように残しておきます。

グローバルリソースを使った方法では、アプリ単位でリソースを作成するため、一つのリソースにまとめて文言などを記載します。

image

このように、「キー」と「値」をペアに記載していくのが、文字のリソースとなります。これをロジックや UI 側で取得していくのが、国際化対応の基本となります。

image

aspx を利用している場合は Literal コントロールを利用したりして抽出する必要があります(コードから設定しない場合)。Validator の ErrorMessage などに設定する場合は直接以下のように記載します。

   1: ErrorMessage="<%$ Resources:MessageResource, ErrorAct1 %>">

Resources の後にリソースファイル名、その後にキー名を指定するだけです。

他にもアプリ全体、または国際化するページ単位で、カルチャの判定方法を追記します。ページ単位の場合は aspx 毎に culture = “auto” と uiCulture = “auto” と追記します。全体の場合は、下記の記述を web.config に追記します。


   1:<globalization culture="auto" uiCulture="auto" />

system.web エントリの要素として記述すると、アプリ全体でクライアントの言語設定を判定するようになります。

と、Web で検索していると大体ここまでで国際化対応できるようになるらしいのですが、自分の場合はこれだけではダメだったのと、どうしても一部 runat = “server” にするとうまくできなかったために、違う方法を組み合わせる必要がありました。

一つは Page の InitializeCulture メソッドをオーバーライドして、言語設定の情報を適用させることです。てっきり、Web.Config やらに記述したものがこれをやってくれるのだと思っていたのですが、何故か動かなかったので・・・。


   1:ProtectedOverridesSub InitializeCulture()
   2:Dim lang = Context.Request.UserLanguages(0)
   3:     Thread.CurrentThread.CurrentCulture = Globalization.CultureInfo.CreateSpecificCulture(lang)
   4:     Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture
   5:MyBase.InitializeCulture()
   6:End Sub

そしてもう一つが、先ほど runat = “server” ではないコントロールに対してリソースを適用しなくてはならなかったので、Reder メソッドをオーバーライドして書き換える処理でした。


   1:ProtectedOverridesSub Render(writer As HtmlTextWriter)
   2:Dim sb As StringBuilder = New StringBuilder
   3:Dim sw As StringWriter = New StringWriter(sb)
   4:Dim hWriter As HtmlTextWriter = New HtmlTextWriter(sw)
   5:MyBase.Render(hWriter)
   6:'runat≠server のリソース適用
   7:Dim html = sb.ToString
   8:Dim matches As MatchCollection = (New Regex("Localize\(([^\))]*)\)", (RegexOptions.Singleline Or RegexOptions.Compiled)).Matches(html))
   9:ForEach match As System.Text.RegularExpressions.Match In matches
  10:         html = html.Replace(match.Value, GetGlobalResourceObject("MessageResource", match.Groups(1).Value).ToString)
  11:Next
  12:     writer.Write(html)
  13:End Sub

何か、他にちゃんとしたやり方がありそうな気もしますが、とりあえず自分の場合はこれらのやり方で国際化対応ができました。

ASP.NET WebAPI で .do な呼び出しに対応する

$
0
0

色々ありまして。

ちょっとしたお仕事上の都合で、現在 struts で用意している Java 製の API 群をどうすればリプレースしやすいか考えていてふと思いついたので試してみました。

やろうとしている事は簡単で、~.do で呼び出された際に Struts ではなく ASP.NET WebAPI で動作させるというものです。そうすることでアプリ側の改修なしにサーバー側をまるっとリプレースすることも選択肢とすることができます。

image

とりあえず WebAPI なプロジェクトを新規に用意します。今回はサンプルですので認証は利用しません。まず最初に行う事は WebAPI 用のコントローラの準備です。

image

今回は空の WebAPI コントローラを利用しますが、どれでも構いません。今回は次のような API を用意します。

   1:Imports System.Net
   2:Imports System.Web.Http
   3:  
   4:Namespace Controllers
   5:PublicClass DoSampleController
   6:Inherits ApiController
   7:  
   8:<HttpGet>
   9:PublicFunction Exec1() AsString()
  10:ReturnNewString() {"Sample API", "8888"}
  11:EndFunction
  12:  
  13:EndClass
  14:End Namespace

これで API 本体は準備できたので、次に WebApiConfig の中で行われている WebAPI 用のルーティング設定を修正し、先ほどの API が呼び出されるようなルーティングを設定します。


   1:Imports System
   2:Imports System.Collections.Generic
   3:Imports System.Linq
   4:Imports System.Web.Http
   5:  
   6:PublicModule WebApiConfig
   7:PublicSub Register(ByVal config As HttpConfiguration)
   8:' Web API の設定およびサービス
   9:  
  10:' Web API ルート
  11:         config.MapHttpAttributeRoutes()
  12:  
  13:         config.Routes.MapHttpRoute(
  14:             name:="DefaultApi",
  15:             routeTemplate:="ht/{action}.do",
  16:             defaults:=NewWith {.controller = "DoSample"}
  17:         )
  18:EndSub
  19:End Module

記載したのは 13 行目から 17 行目の部分で、http://(サーバー)/test/~.do とアクセスした際に呼び出されるような設定となります。

通常であればこれくらいで終わるのですが、今回は ~.do という形式にあるように、静的ファイルへのアクセスと近い形式になり、そのままでは IIS がデフォルトで対応していない拡張子の為、404 エラーとなってしまいます。


   1:<system.webServer>
   2:<handlers>
   3:<removename="ExtensionlessUrlHandler-Integrated-4.0"/>
   4:<removename="OPTIONSVerbHandler"/>
   5:<removename="TRACEVerbHandler"/>
   6:<addname="ExtensionlessUrlHandler-Integrated-4.0"path="*."verb="*"type="System.Web.Handlers.TransferRequestHandler"preCondition="integratedMode,runtimeVersionv4.0"/>
   7:<addname="DoFileHandler"path="*.do"verb="*"type="System.Web.Handlers.TransferRequestHandler"preCondition="integratedMode,runtimeVersionv4.0"/>
   8:</handlers>
   9:</system.webServer>

7 行目にて拡張子 .do に対して TransferRequestHandler を指定し、ASP.NET 側で処理を行えるように指定しています。この設定がないと、静的ファイルとして扱われることとなり HttpHandler を利用する方法で対応することになります。

このような感じで WebAPI を実装すると、.do なアドレスにアクセスすることで Struts 上の API と同様に WebAPI が呼び出されるようになるので、サーバーをまるっと入れ替えることも可能です。

InvokeDelegate アクティビティで「処理」を受け取る

$
0
0

元々存在していたアクティビティの中で、ここまでに取り上げてこなかったものの一つに InvokeDelegate アクティビティがあります。名前からもわかる通り、このアクティビティは、Delegate を Invoke する、つまり受け取った Delegate を呼び出すことができるものです。

Delegate を受け渡すのは、コード上でやる分にはなんてことのない話なのですが、ワークフローデザイナー上でやろうとすると、難易度がどうしてもアップするというかあまり良いやり方が見つかっていません。

MSDN にサンプルがあるので、これを元に説明します。

image

InvokeDelegate アクティビティを用いた「カスタムアクティビティ」のサンプルになります。ワークフロー本体ではなく、カスタムアクティビティというところに注意してください。続いてこのカスタムアクティビティで利用する変数定義です。

image

このカスタムアクティビティは、受け取った処理を全て実行するもので、そのカウンタとなる変数を定義しています。

image

次にカスタムアクティビティとして受け取る「引数」を定義します。ここで定義した引数は、カスタムアクティビティ自体のプロパティとして外部からアクセスできるのですが、今回は Body という変数を「プロパティ」として定義している点に注意が必要です。

プロパティとして定義した場合、カスタムアクティビティのプロパティとなりますので、内部で利用しているアクティビティ群からはアクセスできません。何故プロパティを利用しているかについては、もう少し調査が必要なところです。

そしてもう一つ、この Body と言う引数の型も注意が必要です。ActivityAction<Object> を指定していて、アクティビティの処理を受け取ることができるようになります。

この状態で一度ビルドすることで、このカスタムアクティビティを利用することができます。

image

CustomDelegate としている部分が先ほど作成したカスタムアクティビティです。

image

元々存在する DiaplyName はさておき、カスタムアクティビティの実装で引数に設定したものが追加されています。Items にはカスタムアクティビティに引き渡す値を設定していますが、もう一つの Body には ActivityAction’1 と表示されています。これは、カスタムアクティビティにアクティビティを追加、今回の例でいうと WriteLine アクティビティを追加した際に自動で設定されます。ここの記述によって、カスタムアクティビティに設定されたアクティビティ自身が「処理」として、カスタムアクティビティに伝わる仕組みとなります。

ここで?と思われるのは、親元のワークフロー上では Argument というのが使われていますが、ここまでにそれらしい記述はでてきていません。実際にはこの Argument はカスタムアクティビティの InvokeDelegate アクティビティにて設定したものとなります。

image

InvokeDelegate アクティビティのプロパティをみると、DelegateArguments というプロパティがあります。この設定ボタンをクリックすると次の画面が表示されます。

image

ここでようやく先程ワークフローで利用した Argument が登場します。ここで指定するのは、Argument としてワークフローから受け取る値についてとなります。今回でいうと、Argument には New Object(){1, “ABC”, “TEST”} という配列がわたってきます。これらをループの中で InvokeDelegate で処理するのですが、その際に利用したい値は、受け渡された Object 配列の 1 要素です。それを設定しているのが値の部分で、Items(Index).ToString がそれにあたります。

こうすることで、ワークフロー側で指定した処理 WriteLine がカスタムアクティビティ内部で呼び出されて実行することができるようになります。使いどころが難しいですが、利用できるとワークフローの幅を広げることも可能なのかな、と感じています。

Azure ApiApp テンプレートの VB 版は提供されていない

$
0
0

App Service をちょっと試してみようと思って色々やっているところ、またも VB 使いには悲しい現実を見てしまいました・・・。

これが C# でのプロジェクト選択画面。

image

そしてこれが VB でのプロジェクト選択画面。

image

ええい、みなまで言うな!わかってる、わかってるんだ VB の立ち位置は!

CLR/H #96 with Windows女子部

Azure LogicApps Wait(Delay) Connector の使い方

$
0
0

色々と遊べるはずが非常に難易度の高い状態になっている Azure LogicApps です。
まずは標準で用意されているコネクタの中で、Delay という一定時間待機を行うものがありましたので、それの使い方をまとめておきます。

まず名前が Wait なのか Delay なのかはっきりしろといいたいところですが、今回は Wait で統一して説明します。

コネクタとして設定できる項目は次の 2 パターンです。

image

左側が Action で Delay Until を選択した場合、右側が Delay を選択した場合です。

Until では年、月、日、時間まで指定して待機させることが可能です。使うかどうかは別として、ですが・・・。通常の Delay では待機する分を指定するのみとなっています。

ここで指定できる値は、Int 型にできるものでなくてはなりません。まぁ半角数値で指定するものだと思ってくれれば大丈夫です。

ですが、実際にこのコネクタを利用する際に、常に一定時間待機するのではない場合があります。何らかの計算結果や、ランダムな分数を待機するといった場合が考えられますが、例えばランダムに待機するような場合は、このように指定ができます。

image

上記のように入力した場合、1 ~ 3分待機するように動作します。多分最初の @int は不要で、@rand(1, 3) と記載しても大丈夫なはずです。最初にだけ @ が必ず必要になります

これらは LogicApps で用意されている組み込み関数で、ちょっとした変換や文字列操作、条件判断などが用意されています。MSDNに記載されていますが微妙にわかりにくいです。

LogicApps を利用する上で難易度を高めている原因の一つにデバッグの難しさ、があると思います。今回のケースでいくと、Delay の設定でエラーとなるような値をセットしても、それが原因で動いていないというのを把握できなかったりします。このあたりはもう少しなんらかの手段が用意されるか、方法が見つかるのを期待したいところです。

Azure LogicApps で ApiApps を使うまで

$
0
0

少し前に CLR/H with Windows 女子部・JAZUG・JAWSUG な勉強会にて LT した、Azure LogicApps で遊ぼうな話題ですが、ある程度動かすまでできたので、そこに至るまでの手順をまとめておきます。

環境の構築はスルーしますので、それなりな環境を事前に作っておいてください。

サンプルで作っていたのは Twitter 関係なので、それなりなライブラリを利用するとかいろいろして API を作成します。

   1:public IEnumerable<ResponseTweet> Get()
   2:  {
   3:      (new Credentials()).CreateCredentials();
   4:  
   5:      var tweets = Timeline.GetHomeTimeline(100);
   6:      var res = new List<ResponseTweet>();
   7:      tweets
   8:          .ToList().ForEach(x => res.Add(new ResponseTweet()
   9:          {
  10:              TweetText = x.Text,
  11:              UserAccount = x.CreatedBy.UserIdentifier.ScreenName,
  12:              ID = x.Id
  13:          }));
  14:return res;
  15:  }

例えばこんな感じで。

作成出来たらテストなのですが、今回は Debug/Release で挙動変わるとかもないので、通常通りローカルでテスト実行も可能ですが、本来であれば Azure 環境にデプロイした後にテストすることになるかと思います。

その場合は、Debug でデプロイした後に VS から接続してテストすることになります。

image

サーバーエクスプローラからは Azure 環境に直接接続するメニューが利用できますので、これを使って Debug デプロイしたものに対して接続します。

接続したら実際に実行するのですが、実行には SwaggerUI を利用します。

image

デバッグでもリリースでも、デプロイした後には IE なりブラウザが表示されることと思います。その際のアドレス末尾に /swagger/ と付与することで、Swagger UI が利用できます。この画面から、テストしたい API を選択、値を設定し実行(Try it OUT!)をクリックするとデバッグ実行が行われ、ブレークポイントをたててあれば VS に制御が戻ってきますのでデバッグすることが可能です。

ただし、ここでデバッグできるのは APIApps の中身についてのみで、返却した結果が LogicApps に戻されてからの動作はデバッグできないので注意してください。

と、いうのも現在謎挙動が一つあり、
「APIApps に対してマルチバイトな値を渡した場合、結果が返却されない」
というものがあります。

この確認方法としては、Azure Preview Portal から LogicApps の履歴を確認することになります。

image

実行された LogicApps はこのような形で実行された各回の履歴を参照できます。真ん中に表示されているのが、各 Step 毎の成否で、確認したい Step をクリックすると右端のように個別情報が追加表示されます。

この中で INPUTS LINK から確認できるのが、APIApps に渡された情報で OUTPUTS LINK から確認できるのが、APIApps から戻されている値となります。

image

正常な場合はこのように body 部に結果が設定されているのが確認できるのですが

image

謎挙動時はこのように body 部は空の状態となり、以後のロジックへは何も渡せずに Skip されてしまいます。

この部分の挙動は謎ですが、パラメータでシングルバイトな文字のみ渡していると問題なく動作しているので一応は LogicApps で APIApps を利用することが可能です。


Azure LogicApps のトリガーを実装する

$
0
0

最近は時間があれば LogicApps 周りを触ろうとしていて、WF に通じる(危険な)何かを感じているのもあり、これからに期待したいものとなっています。

LogicApps のトリガーは一定期間単位で処理を繰り返したいといった場合にも利用する、LogicApps の基点となるものです。トリガーを利用しない場合は手動実行する形となります。

公式ドキュメントもありますのでそちらも参照してください。

現状、コードを書く以外の方法で LogicApps のトリガーを作成する手段は見当たりません。内容としては ApiApps の特殊版ですので、ApiApps を作成するのと同じ流れで作業することになりますが、何点かトリガーと認識してもらうためのルールがあります。

まず先にコードを記載します。

   1:publicclass TestController : ApiController
   2: {
   3:     [HttpGet]
   4:     [Route("api/TestTrigger")]
   5:public HttpResponseMessage TestPollTrigger(string triggerState)
   6:     {
   7://サンプルなので何でもよい
   8:         var dt = DateTime.Now.Minute;
   9:if (dt % 2 == 0)
  10:         {
  11:returnthis.Request.EventTriggered();
  12:         }
  13:else
  14:         {
  15:returnthis.Request.EventWaitPoll(new TimeSpan(0, 1, 0));
  16:         }
  17:     }
  18:  
  19:     [HttpPut]
  20:     [Route("api/TestTrigger/{triggerId}")]
  21:public HttpResponseMessage TestPushTrigger(
  22:string triggerId,
  23:         [FromBody]TriggerInput<string, string> triggerInput)
  24:     {
  25:returnthis.Request.PushTriggerRegistered(triggerInput.GetCallback());
  26:     }
  27: }

トリガーの方式としては、ポーリング型とプッシュ型の二つが用意されています。GET でアクセスするのがポーリング型で、PUT でアクセスするのがプッシュ型となります。ポーリング型の場合は、内部で何かしらの処理を行いその結果としてイベントを発生させるか、遅延させるかとなることが多いと思います。反対にプッシュ型ではイベント発生をコールバックしてあげることになります。

そしてトリガーとして認識されるための条件ですが、前述の HTTP メソッドの他に

  • メソッド名に trigger が含まれている(大小文字は問わない)
  • ポーリング型の場合は引数に triggerstate が含まれている
    プッシュ型の場合は引数に triggerId が含まれている

という命名規約を満たしている必要があります。ここを満たしたものだけが、LogicApps 側でトリガとして認識される仕組みです。

それ以外については ApiApps を作る時と同じです。

image

デプロイが成功すればこのように LogicApps でトリガとして利用できるようになります。

Azure Logic app のテンプレ一覧が表示されない場合の対応

$
0
0

いつの間にか気が付いたら、Logic app 新規作成時にテンプレートを選べるようになっていました。

image

Azure のことと言えばこの人、ということでつい最近アップデートされていた模様です。

image

しかし場合によっては以下のように読込エラーとなり、その後なにもできない状態になります。

image

このような状況になる原因は、一つのリソースグループに大量の ApiApp が投入されていることのようで、リソースグループを新規に作成するか、既存リソースの中を整理することで復帰が可能です。

Azure Logic app のテンプレート一覧

$
0
0

直近のアップデートにて追加された Logic app のテンプレート。

結構な数がありますが、どれが何を利用しているのかをまとめましたので、自分が利用したい機能がある場合は参考になるかもしれません。

2015/07/30 現在提供されているテンプレートは以下のものになります。

  • Email from FTP:FTP Connector/SMTP Connector
  • Post Important Email to Yammer:Office 365 Connector/Yammer Connector
  • Backup FTP Folder to Blob Storage:FTP Connector/Azure Storage Blob Connector
  • Protocol Binding:(開けたことがないです・・・)
  • Happy Tweets:Twitter Connector
  • Scatter Gather:HTTP Listner/HTTP
  • Content Based Routing:FTP Connector/BizTalk XML Validator/BizTalk XPath
  • Extractor:BizTalk Transform Service/Microsoft SQL Connector
  • HTTP Request Response:HTTP Listner
  • SQL Job:Microsoft SQL Connector/Twilio Connector
  • EDI X12 Inbound:AS2 Connector/BizTalk EDIFACT/BizTalk Transform Service/Azure Storage Blob Connector
  • One Way Pipeline:HTTP Listner/BizTalk XML Validator/BizTalk Transform Service/Azure Storage Blob Connector
  • Text New Cases:Salesforce Connector/Twilio Connector
  • Create New Cases For Tweets:Twitter Connector/Salesforce Connector

こうしてみると BizTalk 系のテンプレートが思ったよりありますね。使えば面白い事ができる BizTalk なんですが・・・。

Web サービス参照時の認証プロキシ設定

$
0
0

世の中で非常に嫌われている認証プロキシですが、残念ながらこちらの事情とは関係なく導入されているところは多々あると思います。

そのよう環境で外部サービスを参照するようなアプリを作成しようとした場合、プロキシ認証を通らないために泣きそうになることがあります。

Windows 上で設定しているプロキシ設定を利用する場合は、web.config に

   1:<system.net>
   2:<defaultProxy
   3:useDefaultCredentials="true">
   4:</defaultProxy>
   5:</system.net>

と記載することでプロキシを利用するのですが、この設定では認証が必要なプロキシの場合に認証情報が渡せずにエラーとなってしまいます。

いろいろ調べたところ、認証プロキシを利用している場合には以下のようにコーディングを行うことで対応が可能でした。

   1:Dim wr = New WebService.ServiceClient()
   2:Dim bd =TryCast(wr.Endpoint.Binding, BasicHttpBinding)
   3:  
   4:'認証プロキシの設定
   5: bd.ProxyAddress = New Uri(string.Format("http://{0}:{1}", [Proxy Address], [Port No]))
   6: bd.UseDefaultWebProxy = False
   7: bd.Security.Mode = BasicHttpSecurityMode.Transport
   8: bd.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
   9: bd.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic
  10:  
  11:'認証プロキシの認証情報設定
  12: wr.ClientCredentials.UserName.UserName = [UserAccount]
  13: wr.ClientCredentials.UserName.Password = [Password] 

上記のようにバインディングに対して認証プロキシの情報を設定することで、サービス利用時の認証動作を行うことが可能です。

Web サービス参照時の認証プロキシ設定(2) config ファイル使わないパターン

$
0
0

前回のメモと同様に、悩ましくてしょうがない認証プロキシ相手で外部サービスを利用する際の方法です。今回は「諸般の事情」で config ファイルを利用しにくいケースに利用できる方法の一つになります。

実際のコードは以下の通りになります。

   1:Dim client As [Service Interface] = Nothing
   2:Try
   3:Dim myBinding = New BasicHttpBinding()
   4:Dim myEndpoint = New EndpointAddress([Service Address])
   5:Dim myChannelFactory = New ChannelFactory(Of [Service Interface])(myBinding, myEndpoint)
   6:  
   7:'認証プロキシの定義
   8:     myBinding.ProxyAddress = New Uri(string.Format("http://{0}:{1}", [Proxy Address], [Proxy Port]))
   9:     myBinding.UseDefaultWebProxy = false
  10:     myBinding.Security.Mode = BasicHttpSecurityMode.Transport
  11:     myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
  12:     myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic
  13:  
  14:'オレオレ証明書許可対応で呼ぶメソッド設定
  15:'ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf CheckValidationResult)
  16:
  17:'エンドポイントのデフォルト設定を削除
  18:Dim defaultCredentials = myChannelFactory.Endpoint.Behaviors.Find(Of ClientCredentials)()
  19:     myChannelFactory.Endpoint.Behaviors.Remove(defaultCredentials)
  20:  
  21:'認証プロキシの認証情報設定
  22:     ClientCredentials loginCredentials = New ClientCredentials()
  23:     loginCredentials.UserName.UserName = [Account]
  24:     loginCredentials.UserName.Password = [Password]
  25:  
  26:'チャンネルの作成
  27:     myChannelFactory.Endpoint.Behaviors.Add(loginCredentials)
  28:     client = myChannelFactory.CreateChannel()
  29:  
  30:'サービスの実行、結果の取得
  31:Dim apiRet = client.[Service Method](New [Service Class](New [Service Body Class]([Parameter]))).Body.@return
  32:  
  33:'チャンネルの終了
  34:DirectCast(client, ICommunicationObject).Close()
  35:  
  36:Catch ex As Exception
  37:  
  38:If client IsNotNothingThen
  39:DirectCast(client, ICommunicationObject).Abort()
  40:EndIf
  41:  
  42:EndTry
  43:  

config ファイルを用いた初期化処理を、コードで力技にて実行する形ですね。

ポイントとなったのは認証情報の設定方法で、デフォルトで登録される設定を削除しておかないと、うまいこといかないという点です。

そしてここまで試した後で @kazukさんよりすばらしい情報が・・・!

AppDomain を自分で作成することで、好きな場所の config ファイルを扱えるようになるとのことですので、これも試してみようと思います。

Viewing all 208 articles
Browse latest View live