WCF RESTサービスとUWPアプリケーション







UWP用に開発しようとしている人々に生じるかなり一般的な質問は、「UWPアプリケーションがSQL Serverデータベースからデータを取得する方法は?」です。 直接データを取得できません。 UWPアプリケーションのデータベースを操作するには、構成済みのWebサービスが必要です。



クライアントアプリケーション開発者は通常、サーバーバックエンドの作成にはほど遠いですが、少なくともサービスについて理解している必要があります。



猫の下には、ローカルWCF RESTサービスを作成し、UWPアプリケーションでデータを取得する方法の説明があります。 サービスは、Azureで作成されたSQL Serverデータベースからデータを取得できます(ただし、同様に、任意のローカルデータベースからデータを取得できます)。 さらに、すべてがあまり見栄えの悪いものにならないように、同じクライアントUWPアプリケーションから動作するようにAzureにサービスを配置する可能性を検討します。



RESTサービスの作成



UWPアプリケーションをテストするために、簡単なサービスを作成します。 数年前にバックエンドを書くことに最後に興味を持っていたので、Web API 2サービスではなく、WCFの作成について説明します(これには利点があるためではありません)。







自動的に作成されるサンプルコードを削除します



削除されるコード
IService1.csから

[OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: Add your service operations here // Use a data contract as illustrated in the sample below to add composite types to service operations. [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } }
      
      





Service1.svc.csから



  public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; }
      
      







次のコントラクト操作とクラスコードをIService1.csに追加します。



  [ServiceContract] public interface IService1 { [WebGet(UriTemplate = "/GetScheduleJson", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] List<Timetable> GetScheduleJson(); } [DataContract] public class Timetable { [DataMember] public int id { get; set; } [DataMember] public DateTime arrivaltime { get; set; } [DataMember] public Int16 busnumber { get; set; } [DataMember] public string busstation { get; set; } }
      
      





ArrivaltimeフィールドはTimeSpan型で作成できますが、DateTime型を使用すると、後でJSONで作業する方がはるかに便利です。 コントラクト操作では、WebMessageFormat.Xml形式も指定できます。 操作自体はWebGet属性でマークされます。つまり、結果を返します。 コードの実行のみが必要な場合は、WebInvoke操作をマークできます。



また、Service1.svc.csに次のコードを追加します。



  public List<Timetable> GetScheduleJson() { return GetSchedule(); } private List<Timetable> GetSchedule() { List<Timetable> Schedule = new List<Timetable> { new Timetable { id=1, arrivaltime=DateTime.Parse("12:05:00"), busnumber=5, busstation ="" }, new Timetable { id=2, arrivaltime =DateTime.Parse("12:10:00"), busnumber=5, busstation =" " } }; return Schedule; }
      
      





Web.configの構成を簡素化します。 動作セクションにendpointBehaviorを追加します。



  <endpointBehaviors> <behavior name="restBehavior"> <webHttp /> </behavior> </endpointBehaviors>
      
      





次に、behaviourタグの既存のコードで、name属性に値「servicebehavior」を追加します。



  <serviceBehaviors> <behavior name="servicebehavior"> <!-- To avoid disclosing metadata information, set the values below to false before deployment --> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors>
      
      





system.serviceModelタグのルートで、サービスとエンドポイントを追加できます。



  <services> <service name ="ServiceForUWP.Service1" behaviorConfiguration ="servicebehavior" > <endpoint name ="RESTEndPoint" contract ="ServiceForUWP.IService1" binding ="webHttpBinding" address ="" behaviorConfiguration ="restBehavior"/> </service> </services>
      
      







完成したサービスを取得します。



デバッグを起動し(ソリューションエクスプローラーでプロジェクトを選択する必要がある)、ブラウザーで開く(私の場合、ポート64870)

http://localhost:64870/Service1.svc/GetScheduleJson





JSONの形式で結果を取得します。

[{"Arrivaltime": "\ / Date(1487408400000 + 0300)\ /"、 "busnumber":5、 "busstation": "Birch"、 "id":1}、{"arrivaltime": "\ / Date( 1487408700000 + 0300)\ / "、" busnumber ":5、" busstation ":" Children's World "、" id ":2}]



何らかのパラメーターでフィルター処理されたデータを返したい場合は、操作を同様の操作に変更できます。



  [WebGet(UriTemplate = "/GetScheduleJson/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] List<Timetable> GetScheduleJson(int id);
      
      





メソッドを実装する
 List<Timetable> GetScheduleJson(int id)
      
      



アドレスhttp://localhost:64870/Service1.svc/GetScheduleJson/1



て結果を取得します。 この場合、1はメソッドに渡されるパラメーターです。



UWPクライアントアプリケーションの作成



UWPアプリケーションからデータを取得するのは簡単です。 2つのオプションがあります:Windows.Web.Http.HttpClientまたはSystem.Net.Http.HttpClientを使用します。



両方のクライアントをUWPアプリケーションで使用できます。 Webは少し​​新しく(8.1でリリースされました)、UWPでのネイティブ開発により適しています。 ASP.NETアプリケーションまたは他のモバイルプラットフォーム用のXamarinアプリケーションでコードを使用する予定がある場合は、Netクライアントを使用することをお勧めします。 さらに、Webクライアントには現在、より多くの設定と機能があります(たとえば、認証に特別なSSL証明書を使用する機能など)。



実際、UWPアプリケーションの.NET Coreでは、System.Net.HttpはWindows.Web.Httpコンポーネントのラッパーです。 ただし、このラッパーは、.NETのSystem.Net.Httpスペースと同じAPIをサポートしています。



以下は、サービスからデータを受信する2つの簡単な例です。



 var uri = new Uri("http://localhost:64870/service1.svc/GetScheduleJson"); var client = new Windows.Web.Http.HttpClient(); var json = await client.GetStringAsync(uri); var uri = new Uri("http://localhost:64870/service1.svc/GetScheduleJson"); System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(); System.Net.Http.HttpResponseMessage responseGet = await client.GetAsync(uri); string json = await responseGet.Content.ReadAsStringAsync();
      
      





データを逆シリアル化するには、NuGetパッケージNewtonsoft.Jsonを使用できます。



 List<Timetable> appsdata = JsonConvert.DeserializeObject<Timetable>(json);
      
      





もちろん、Timetableクラスコードを追加する必要があります(サービスアプリケーションとまったく同じです)。



AzureでのSQL Serverデータベースの作成



Azureでのデータベースの作成は簡単です。 ポータルに移動して、次のフィールドに入力する必要があります。







価格カテゴリを選択するだけです。 価格は月額5米ドルからです。 この金額は、 Dev Essentialsの無料登録から受け取ったボーナスで完全にカバーされます(25 USDが毎月1年間与えられます)。 登録するときは、カードを添付する必要があります。 このような登録の場合、原則として、追加のカードが作成され、その制限を調整できます。



この場合、データベースへのASP.NET(SQL認証)接続文字列は次のようになります。



 Server=tcp:timetableserverok.database.windows.net,1433;Initial Catalog=timetabledb;Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
      
      





Azureポータルのデータベースプロパティに移動して確認できます。 現在のマシンからデータベースにアクセスできるようにするには、そのIPをファイアウォールリストに追加する必要があります。







サーバーエクスプローラーのVisual Studioウィンドウから編集可能











テーブルを作りましょう







そして、テストデータを作成します。



SQL Serverデータベースからサービスデータを取得する



データベースからデータを「プル」するには、サービスの設計に小さな変更を加える必要があります。 2つの名前空間を追加します。



 using System.Data; using System.Data.SqlClient;
      
      





SQL Serverデータベース接続文字列のテキストを含む変数:



 public string ConnectionString = "Server=tcp:timetableserverok.database.windows.net,1433;Initial Catalog=timetabledb;Persist Security Info=False;User ID=alexej;Password=_;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
      
      





Azureで新しく作成したデータベースを使用しますが、既に述べたように、ローカルデータベースを含む任意のデータベースに接続できます(この場合、接続文字列はもちろん置き換える必要があります)。



ここで、データベースからデータを「プル」するには、GetScheduleメソッドのコードを次のように変更する必要があります。



  private List<Timetable> GetSchedule() { using (DataSet ds = new DataSet()) { using (SqlConnection sqlCon = new SqlConnection(ConnectionString)) { try { sqlCon.Open(); string sqlStr = "select * from Timetable"; using (SqlDataAdapter sqlDa = new SqlDataAdapter(sqlStr, sqlCon)) { sqlDa.Fill(ds); } } catch { return null; } finally { sqlCon.Close(); } } List<Timetable> Schedule = new List<Timetable>(); using (DataTable dt = ds.Tables[0]) { foreach (DataRow dr in dt.Rows) { Schedule.Add(new Timetable() { id = Convert.ToInt16((dr["ID"])), arrivaltime = DateTime.Parse(dr["arrivaltime"].ToString()), busnumber = Convert.ToInt16((dr["busnumber"] ?? 0)), busstation = dr["busstation"].ToString() }); } } return Schedule; } }
      
      





クラウドサービスの作成



Azureでサービスをホストするには、 Azure SDK for .NET (約450 MB)をダウンロードしてインストールし、特別な種類のクラウドサービスの新しいプロジェクトを作成する必要があります。







役割を選択し、好みに合わせて名前を変更します







その結果、AzureCloudServiceTimetableとTimetableServiceの2つのプロジェクトが作成されます。

2番目(TimetableService)では、ローカルサービスからコードをコピーできます。 つまり-ファイルIService1.cs、Service1.svc.cs、Web.configの内容。 その後、プロジェクトをテストできます。 公開する前にWeb.configファイルに変更を加えることができます。 タグ内



 <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      
      





値をfalseに変更します



Azureに発行するには、パッケージを作成する必要があります。 AzureCloudServiceTimetableプロジェクトで、コンテキストメニューを呼び出して[パッケージ]を選択する必要があります。







プロセスが完了すると、パッケージと構成ファイルのあるディレクトリが開きます。

ポータルのWebインターフェイスを使用してAzureに発行できます。 ポータルに行きます。 クラウドサービス(クラシック)のアイテムを選択し、新しいものを作成してフィールドに入力します







2つのチェックボックスを選択する必要があります:「1つ以上のロールに個別のインスタンスが含まれている場合でも展開する」と「展開を起動する」。 展開および起動後(起動には時間がかかる場合があります)、URIでリクエストを行うことができます。



http://servicetimetable.cloudapp.net/Service1.svc/GetScheduleJson







このアドレスは、UWPアプリケーションで使用できます。 展開の詳細: クラウドサービスの作成と展開



PS:ユーザーdmitry_dvmに説明/編集をありがとう



All Articles