Windows ストアアプリから Windows Azure へアクセスする(その2)
10月4日-5日に開催された、Developer Camp 2012 Japan Fall にて、「デバイス + クラウドで実現するこれからのサービス ~ Windows 8 + Windows Azure 編 ~」を担当させていただきました。
本エントリーは前回説明しました、「Windows ストアアプリから Windows Azure へアクセスする(その1)」の続きになります。Azure 側の環境構築と、ベースとなる Azure サービスを作成し、デプロイしてみるところまで行きましたので、今回は Windows Azure から画像と詳細情報を公開するロジックを追加して、再デプロイするところまで行きましょう。
ASP.NET MVC アプリケーションの作成
前回作成した PicMgr.WebApi プロジェクトにモデル クラスを追加します。
[Models] フォルダを右クリックして [追加] – [クラス] を選択します。
クラス名を”Picture.cs” にします。内容を以下のコードに置き換えます。
namespace PicMgr.Models { using System.Runtime.Serialization; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System; [DataContract] public class Picture { [Key] public int PrimaryKey { get; set; } [DataMember] public string UniqueId { get; set; } [DataMember] public string Title { get; set; } [DataMember] public string SubTitle { get; set; } [DataMember] public string Description { get; set; } [DataMember] public string ImagePath { get; set; } } }
[参照設定] で”System.Runtime.Serialization” を追加します。ここで一度 [Shift] + [Ctrl] + [B] キーを押してビルドしてください。
次に、[Controllers] フォルダを右クリックして[追加] – [コントローラー] を選択します。
コントローラー名を「PicturesController」、モデルクラスは「Picture (PicMgr.Models)」を選択、データコンテキストクラスは新規で「PicMgr.WebApi.Models.PictureContext」をデータコンテキスト型として入力し、追加ボタンを押します。
ModelsフォルダにPictureContext.csが作成されていることを確認します。
PictureContext.cs の内容は以下のようになっているはずです。
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; using PicMgr.Models; using PicMgr.WebApi.Models; namespace PicMgr.WebApi.Controllers { public class PicturesController : ApiController { private PictureContext db = new PictureContext(); // GET api/Pictures public IEnumerable<Picture> GetPictures() { return db.Pictures.AsEnumerable(); } // GET api/Pictures/5 public Picture GetPicture(int id) { Picture picture = db.Pictures.Find(id); if (picture == null) { throw new HttpResponseException( Request.CreateResponse(HttpStatusCode.NotFound)); } return picture; } // PUT api/Pictures/5 public HttpResponseMessage PutPicture(int id, Picture picture) { if (ModelState.IsValid && id == picture.PrimaryKey) { db.Entry(picture).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { return Request.CreateResponse( HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.OK); } else { return Request.CreateResponse( HttpStatusCode.BadRequest); } } // POST api/Pictures public HttpResponseMessage PostPicture(Picture picture) { if (ModelState.IsValid) { db.Pictures.Add(picture); db.SaveChanges(); HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, picture); response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = picture.PrimaryKey })); return response; } else { return Request.CreateResponse( HttpStatusCode.BadRequest); } } // DELETE api/Pictures/5 public HttpResponseMessage DeletePicture(int id) { Picture picture = db.Pictures.Find(id); if (picture == null) { return Request.CreateResponse( HttpStatusCode.NotFound); } db.Pictures.Remove(picture); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { return Request.CreateResponse( HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.OK, picture); } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } } }
サンプルデータの挿入と Windows Azure SQL データベースへの移行、Web Sites へのデプロイ
パッケージマネージャーコンソールを表示します。[ツール] - [ライブラリパッケージマネージャー] - [パッケージマネージャーコンソール] を選択します。
コンソールから次の2つのコマンドを順番に実行します:
enable-migrations -ContextTypeName PicMgr.WebApi.Models.PictureContext
add-migration Initial
[Migrations] フォルダがが作成されていることを確認し、”Configuration.cs” を開きます。
PicMgr.Models 名前空間の宣言を追加します。namespace PicMgr.WebApi.Migrations { using System; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; using PicMgr.Models; ...
Seed メソッドに以下のコードを追加して、データの挿入を行います。 (ご自分の Azure 環境でお試しになる際は、下記コード内の BLOB URL から画像を入手し、ご自分の Azure Storage BLOB へアップロードした上で URL を置き換えてください。)
protected override void Seed( PicMgr.WebApi.Models.PictureContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // string dummy = "\n\nPellentesque porta, mauris quis interdum vehicula, urna sapien ultrices velit, nec venenatis dui odio in augue. Cras posuere, enim a cursus convallis, neque turpis malesuada erat, ut adipiscing neque tortor ac erat."; context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1001", Title = "January", SubTitle = "January", Description = "お正月" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Jan.jpg" }); context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1002", Title = "February", SubTitle = "February", Description = "バレンタインデー" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Feb.jpg" }); context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1003", Title = "March", SubTitle = "March", Description = "ひな祭り" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Mar.jpg" }); context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1004", Title = "April", SubTitle = "April", Description = "桜吹雪" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Apr.jpg" }); context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1005", Title = "May", SubTitle = "May", Description = "風薫る" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_May.jpg" }); context.Pictures.AddOrUpdate(p => p.UniqueId, new Picture { UniqueId = "1006", Title = "June", SubTitle = "June", Description = "梅雨" + dummy, ImagePath = "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Jun.jpg" }); context.SaveChanges(); }
パッケージマネージャーコンソールに戻り、以下のコマンドを実行します。
update-database
ビルドします。これで Azure アプリケーションは完成です。
Azure Web Sites へのデプロイと動作確認
ソリューション エクスプローラーから [PicMgr.WebApi] プロジェクトを右クリックし、[発行…] メニューを選択します。
前回のエントリーと同様に「Web を発行」ダイアログが表示されますので、[設定] タブを選択します。[データベース] の下にある [PictureContext] にリモート接続文字列を入力します。右の[…] を選択し、こちらも前回のエントリーで作成した SQL データベースに接続するための設定情報を参考に以下のように入力します。[テスト接続] ボタンを押してデータベースに接続できることを確認し、[OK] ボタンを押します。
[この接続文字列を実行時に使用する(更新先 web.config)] 及び [Code First Migrations を実行する(アプリケーションの起動時に実行する)] をチェックし、[次へ >] ボタンを押して、[プレビュー] タブから [発行] ボタンを押します。
アプリケーションが発行されてデプロイが完了すると、前回のエントリーと同様に Web API 対応アプリのデフォルト ページが表示されます。
今度は URL の後ろに”api/pictures”を追加して、JSON データの内容を確認します。HTTP GET が PicturesController クラスの GetPictures メソッドにバインドされ、SQL データベースへアクセスし、以下のように先ほど Seed メソッドで挿入された内容が返されるはずです。
[ {"UniqueId":"1001","Title":"January","SubTitle":"January", "Description":"お正月 ...(省略)","ImagePath": "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Jan.jpg"}, ...(省略) {"UniqueId":"1006","Title":"June","SubTitle":"June", "Description":"梅雨 ...(省略)","ImagePath": "https://claudiapicmgr.blob.core.windows.net/pictures/Claudia_Jun.jpg"} ]
Windows Azure Web Sites にクラウドサービス環境を作成し、アプリケーション フレームワーク技術としては ASP.NET MVC Web API、Entity Framework を活用することで、非常に簡単かつ素早く Azure 対応クラウドサービスが作成できることが実感できましたでしょうか?また、Web Sites の高速簡単デプロイ、デスクトップ上の Web サービスが何のコード変更なしに SQL データベースへの移行も含めてクラウド環境に乗っかってしまうのも、なかなか魅力的ではないかと思います。本エントリーではアプリケーション開発の手順を中心に説明していますが、もう少し詳しく知りたい方は英語ですが「Deploying an ASP.NET Web Application to a Windows Azure Web Site and SQL Database」 が参考になるかと思います。
いよいよ次のエントリーでは、Windows ストアアプリからこの Web サービスへアクセスして返された JSON データをグリッドビューにバインドして表示させます。