ビジネス Windows ストアアプリ開発とアーキテクチャー Part 2: REST サービスの実装

皆様、こんにちは!

早速、前回の続きに参りましょう。今回は、ASP.NET Web API を使ってどのようにREST サービスを実装するか、というところになります。Windows ストアアプリからリモートデータを使用するためには、なんらかの REST または SOAP サービスを公開する必要があります。このサンプルでは、Windows ストアアプリから基本的なデータ操作ができるようなサービスを作成します。

1. 前回使用した EFModel ソリューションを Visual Studio 2012 で開きます。

2. 当該ソリューションを右クリックして、新しいプロジェクトの追加、を選択しクリックします。

3. ASP.NET MVC 4 Web Application を選択し、名前を適当につけます(ここでは RestService)。

4. OK ボタンをクリックします。

image

5. 次に出てくるダイアログボックスで、Web API を選択し、OKをクリックします。

6. REST サービスの初期のスケルトンが作成されます。

image

7. EFModel プロジェクトに参照設定を追加します。次いで、Controller を実装します。

8. RestService プロジェクトのController フォルダーを右クリック->追加->コントローラーを選択します。

image

9. CookBookAppController という名前にして、OK をクリックします。

 

image

このコントローラーを下記の通り実装します :

 using DataModel;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net;
 using System.Net.Http;
 using System.Web.Http;
 using System.Globalization;
  
 namespace RestService.Controllers
 {
     public class CookBookAppController : ApiController
     {
         // GET CookBookApp
         [HttpGet]
         public List<Place> Place()
         {
             /// return new string[] { "value1", "value2" };
             /// 
             try
             {
                 using (CookBookApp ctx = new CookBookApp())
                 {
                     var lst = ctx.Places.ToList();
                     return lst;
                 }
             }
             catch (Exception)
             {
                 throw;
             }
  
         }
  
         // GET CookBookApp/5
         [HttpGet]
         public Place Place(int id)
         {
             try
             {
                 using (CookBookApp ctx = new CookBookApp())
                 {
                     return ctx.Places.Where(x => x.PlaceID == id).FirstOrDefault();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
         }
         // GET CookBookApp/5
         [HttpGet]
         public IEnumerable<Place> Search(string queryText)
         {
             try
             {
                 //queryText = queryText;
                 using (CookBookApp ctx = new CookBookApp())
                 {
  
                     var lst11 = ctx.Dishes.Where(x => x.Name.ToLower().Contains(queryText.ToLower())).Select(x => x.DishID).ToList();
                     var lst22 = ctx.Towns.Where(x => x.Name.ToLower().Contains(queryText.ToLower())).Select(x => x.TownID).ToList();
  
                     var lst = ctx.Places.ToList();
  
                     var ll = from p in ctx.Places
                              where
                              lst11.Contains(p.DishID) ||
                              lst22.Contains(p.TownID) ||
                              p.Name.ToLower().Contains(queryText.ToLower()) ||
                              p.Message.ToLower().Contains(queryText.ToLower())
  
                              select p;
  
                     var rr = ll.ToList();
                     return rr;
                 }
             }
             catch (Exception)
             {
                 throw;
             }
         }
  
         // POST CookBookApp
         [HttpPost]
         public void Place([FromBody]Place plc)
         {
             try
             {
                 if (plc == null)
                     return;
                 using (CookBookApp ctx = new CookBookApp())
                 {
                     if (plc.PlaceID == -1)
                     {
                         ctx.Places.Add(plc);
                         ctx.SaveChanges();
                     }
                     else
                     {
                         var p = ctx.Places.Where(x => x.PlaceID == plc.PlaceID).FirstOrDefault();
                         if (p == null)
                             return;
  
                         p.Name = plc.Name;
                         p.Message = plc.Message;
                         p.Description = plc.Description;
                         p.DishID = plc.DishID;
                         p.TownID = plc.TownID;
                         p.Image = plc.Image;
                         ctx.SaveChanges();
                     }
                 }
             }
             catch (Exception)
             {
                 throw;
             }
         }
  
  
         // DELETE CookBookApp/5
         [HttpGet]
         public List<int> DPlace(int id)
         {
             try
             {
                 using (CookBookApp ctx = new CookBookApp())
                 {
  
                     var p = ctx.Places.Where(x => x.PlaceID == id).FirstOrDefault();
                     if (p == null)
                         return new List<int>() { 0 };
  
                     ctx.Places.Remove(p);
                     ctx.SaveChanges();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
  
             return new List<int>() { 1 };
         }
  
         // GET Town
         [HttpGet]
         public List<Town> Town()
         {
             /// return new string[] { "value1", "value2" };
             /// 
             try
             {
                 using (CookBookApp ctx = new CookBookApp())
                 {
                     return ctx.Towns.ToList();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
  
         }
  
         // GET Dish
         [HttpGet]
         public List<Dish> Dish()
         {
             /// return new string[] { "value1", "value2" };
             /// 
             try
             {
                 using (CookBookApp ctx = new CookBookApp())
                 {
                     // var ss= ctx.Dishes.ToString();
                     return ctx.Dishes.ToList();
                 }
             }
             catch (Exception)
             {
                 throw;
             }
         }
     }
 }

SQL Server に test ユーザーを作り、これでログインを行います。Connection String を編集します。下記のようにSQL Server Management Studio で適切に設定を行います。

image

※この test ユーザーでローカルホストの SQL Express に SQL Server 認証でログインできるかどうかをまずは確認してください。インストール時、SQL Express を普通にインストールすると、Windows 認証モードになっているはずです。これをSQL Server Management Studio のサーバーのプロパティを開いて混合モードに変更しないと、ログインができません。

image

また、クライアントプロトコルも、TCP/IPや、名前付きパイプが有効になっていることを確認してください。

image

なお、変更した後は、SQL Server 構成マネージャーで、再起動を行わないと変更が反映されませんので、注意してください。

image

詳しくはこのあたりをご覧ください。

https://msdn.microsoft.com/ja-jp/library/ms188670.aspx

https://msdn.microsoft.com/ja-jp/library/ms190737(v=sql.100).aspx

https://msdn.microsoft.com/ja-jp/library/ms345416(v=sql.100).aspx

https://msdn.microsoft.com/ja-jp/library/ms175496(v=sql.105).aspx

12. Web.Config ファイルに、下記のように、ConnectionString を追加します。

 <connectionStrings>
   <add name="cookbook_db" 
         providerName="System.Data.SqlClient" 
         connectionString="Data Source=.\sqlexpress;
         Initial Catalog=cookbook_db;Persist Security Info=True;
         User ID=testuser;Password=(適当に決めてください);"/>
 </connectionStrings>

13. RestService をスタートアッププロジェクトに設定して、実行します。

14. Internet Explorer が起動したら、

image

下記のアドレスを入力します : ※ ポート番号は適宜読み替えてください。

https://localhost:38304/cookbook/place

image

ファイルを開く、を選択するとメモ帳が立ち上がり、データベースから全ての Places が取得できます。

image

このデータは、前回実行した EF Test コンソールアプリケーションが挿入したものです。

.json ファイルを、メモ帳に関連付けしてありますWebMatrix をインストールすると、自動的に WebMatrix に関連付けされてしまうので、関連付けを変更しておいてください。もし、Fiddler を使っている場合には、そちらに関連付けるのも便利かもしれません。

以上です。

この後、完成品のアプリを作成してご紹介しますので、このエントリの続編をご期待ください。

鈴木 章太郎