Open Data Protocolの実装 – Share Point Server 2010のデータを操作する
今回はOpen Data Protocolの実装 – Share Point Server 2010のデータを操作するをご紹介します。(2/24に実施されたTechDaysセッションのフォローアップも兼ねています)
このシリーズの目次は以下になります。
1) WCF Data Servicesの新機能 – 射影
2) WCF Data Servicesの新機能 – カウント
3) WCF Data Servicesの新機能 – Server Driven Paging(SDP)
4) WCF Data Servicesの新機能 – Feed Customization
5) WCF Data Servicesの新機能 – データバインド
6) WCF Data Servicesの新機能 – カスタムプロバイダ1
7) WCF Data Servicesの新機能 – カスタムプロバイダ2
8) WCF Data Servicesの新機能 – リクエストパイプライン
9)Open Data Protocolの実装 – Share Point Server 2010のデータを操作する
■Open Data Protocol(OData)について
データをさまざまな環境で共有するための規約となります。
RESTfulなプロトコルであり、フォーマットにはAtomPubとJsonが既定されています。
ぶっちゃけ、WCF Data Servicesで使用していたフォーマットと手法がODataに採用されたといったところが実情でしょう。
サービスを作成するのは確かにWCF Data Servicesなのですが、ODataはMS非MS問わず、さまざまなサービスやプロダクトで採用され始めています。(下記)
それらとのデータのやりとりが全て同じ手法で行なうことができると言うのが最大のメリットのひとつでしょう。ちなみに、SOAP形式のサービスでも可能だったよね、と思う方がいるかも知れませんが、ODataははじめからデータ可搬を目的にしている点がことなります。SOAP形式で苦手であった、グラフオブジェクトのシームレスな転送なども可能です。あと、やっぱりHTTPのGetで取得できるのは気持ちいいですよね。SOAPの場合はデータの取得でもPOSTを発行するわけで、ちょっとブラウザでと言うわけにはいきません。
サーバー製品
−SharePoint 2010
−SQL Server Reporting Services 2008 R2
−SQL Azure
−IBM WebSphere eXtreme Scale
−Microsoft Media Room
−WCF RIA Services
−WCF Data Services
外部サービス
−Netflix
−Nerd Dinner
−Mix 2010
−Vancouver’s vanGuide
−Open Government Data Initiative
−Open Science Data Initiative
−Microsoft Codename “Dallas”
−City of Edmonton
例えば、先日ラスベガスで行なわれたMixというイベントでは、セッションの情報がOData形式で公開されていました。(MixはOData祭りだったらしいです、参加できなくて残念)
https://api.visitmix.com/OData.svc/
これをVS2010でサービス参照の追加を用いてデータの取得を行なうことが可能です。
外部にWCF Data Servicesで作成されたサービスが立っているようなものですね。
ODataに関しては以下のサイトが総本山です。
https://www.odata.org/
SDKもありますので、開発関係はこちらから
https://www.odata.org/developers/odata-sdk
■SharePoint Server 2010(サービスとして)
と言うわけで、SharePoint Server 2010もOData形式でデータ操作が行なえるプロダクトのひとつですので、これでデモを行ないますね。
まず環境作成ですが、松崎師匠ブログの以下を参照に作成します。
https://blogs.msdn.com/tsmatsuz/archive/2009/12/01/sharepoint-2010-development-overview.aspx
私はSharePoint FoundationのBeta2をインストールしました。
適当にサイトを立てて(立てなくとも既定でOKです)共有ドキュメントにファイルを4つ追加しました。
これらをODataを用いて操作してみます。
まずサービスのエンドポイントですが、以下のようになります。
https://サイトのアドレス/_vti_bin/listdata.svc
ここにアクセスすると、以下のようにSharePointServerがもつさまざまなエンティティを確認することが可能です。
当然ながら、https://サイトのアドレス/_vti_bin/listdata.svc/お知らせと指定すれば、お知らせの一覧が取得できます。今までWCF Data Servicesを扱っていたのと全く変わりありません。
もちろん、データの取得だけでなく、追加更新削除も、URLを通じた手法で操作することが可能です。(認証は必要ですけど)
■SharePoint Server 2010(クライアントからの使用)
ではVisual Studioで使用してみることにします。サービス参照の追加をすれば、、、
とまぁ、見慣れた状況になります。
後はコーディングするだけです。今回はWPFでアプリケーションを作成してみます。
private ServiceReference1.デモサイトDataContext context; private void Window_Loaded(object sender, RoutedEventArgs e) { context =new ServiceReference1.デモサイトDataContext( new Uri("https://localhost/sites/demo/_vti_bin/listdata.svc")); context.Credentials = CredentialCache.DefaultCredentials; var res = (from p in context.共有ドキュメント orderby p.更新日時 descending select p).ToList(); lstBox.ItemsSource = res; } |
こんな感じです。(日本語が混じるのがちょっとイケてないですが、、、)とにかく実行してみます。追加した共有ドキュメントのリストが取得できていますね。
共有ファイル自体にアクセスはできないの?と思った方もいるかもしれません。
もちろん可能です。WCF Data Servicesには、Blob(Binary Large Object)ファイルをストリームとして扱う新機能が追加されています。
SharePointServer2010は、サービス実装としてその実装も行なっています。
クライアント側で、その恩恵を受けてみましょう。上記の出力ボタンを押したコードを紹介します。
private void btnSave_Click(object sender, RoutedEventArgs e) { ServiceReference1.共有ドキュメントItem sd = (ServiceReference1.共有ドキュメントItem)lstBox.SelectedItem; var response = context.GetReadStream(sd); byte[] buffer = new byte[1000]; int count = 0; using (FileStream fs = new FileStream(@"c:\" + sd.名前, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { while (response.Stream.CanRead && (0 < (count = response.Stream.Read(buffer, 0, buffer.Length)))) { fs.Write(buffer, 0, count); } } } |
選択した共有ドキュメントを、Cドライブの直下に作成します。
このときにストリーム形式を用いていることが分かります。共有ドキュメントItemエンティティにはバイナリファイル自信のメンバーはありません。仮にメンバーにBlob自体があった場合、共有ドキュメントItemエンティティのアクセスのボトルネックになりますよね。そうしたサービスの懸念点を、このBlobストリームの形式は解消してくれます。
クライアントでの使用ではなく、サービスを作成するときにこのストリームの機能を追加する場合は、(カスタムプロバイダやEntityProviderに機能を追加することになりますが、、、)IDataServiceStreamProviderの実装が必要になります。この例も機会があったら掲載しようかと思いますが、今回はこれにて力つきました・・・
ちなみに、折角WPFなので、Windows7のジャンプリストにSharePointのお知らせを追加してみたいと思います。
App.xaml.csに以下を記述します。
private void Application_Startup(object sender, StartupEventArgs e) { //ジャンプリストクリア JumpList jumpList1 = new JumpList(); jumpList1.Apply(); //ジャンプリスト追加 SetMyJumpList(); } private void SetMyJumpList() { ServiceReference1.デモサイトDataContext dc = new ServiceReference1.デモサイトDataContext( new Uri("https://localhost/sites/demo/_vti_bin/listdata.svc")); dc.Credentials = CredentialCache.DefaultCredentials; var query = (from p in dc.お知らせ orderby p.更新日時 descending select p).ToList(); JumpList jumpList1 = new JumpList(); foreach (var q in query) { JumpTask jumpTask1 = new JumpTask(); jumpTask1.Title = q.タイトル; jumpTask1.Description = Regex.Replace(q.本文, @"<([^>]|\n)*>", ""); jumpTask1.ApplicationPath = "https://localhost" + q.パス; jumpTask1.IconResourcePath = Assembly.GetExecutingAssembly().Location; jumpTask1.CustomCategory = q.コンテンツタイプ; jumpList1.JumpItems.Add(jumpTask1); } JumpList.SetJumpList(this, jumpList1); } |
実行すると以下のようになります。ジャンプリストも色々なアイデアで使いやすいインターフェイスの実現ができそうです。
今回作成したデモは以下になります。(あまり意味は無いような気がしますが)
[https://cid-f1df6ad9b682ecf0.skydrive.live.com/self.aspx/2010^_TechDays/WPFDemo.zip](https://cid-f1df6ad9b682ecf0.skydrive.live.com/self.aspx/2010%5E_TechDays/WPFDemo.zip "https://cid-f1df6ad9b682ecf0.skydrive.live.com/self.aspx/2010^_TechDays/WPFDemo.zip
")
ひとまずこれで、今回の連載は終了となります。ウォッチされていた方お疲れ様でした。
(何か思いついたら、追記するかもしれませんけど)