DHJJ DHJJ [Hatsune's Journal Japan]

Windows Azure + Windows Phone 7 入門

Windows Azure + Windows Phone 7 入門

01

Windows Azureについて

Azureってなんだっけ?

02

今回のセッションでは、「Web Role」と「SQL Azure」というPaaSとしてWindows Azureを活用します。

※注:Windows Azure [P]latformと「P」は大文字が正式にということに決定したそうです。

 AzureとWP7は同じ開発環境で開発可能

03

まずは開発環境で動作を確認し、それが終わったらWindows Phone 7アプリはWindows Phone 7の実機(HTC 7 Torphy)へデプロイし、Windows AzureアプリはAzureへデプロイして、最後は実行環境で動作を確認します。

Windows Azure SDK 1.3

04

Azureを簡単に使うには

05

今回のセッションではセッション前日にリリースされたASP.NET MVC 3日本語版を使います。

しかし、Windows Azure SDK 1.3には、まだASP.NET MVC 3のテンプレートがはいってません。そこで、ASP.NET MVC 3で作成しておいて、あとからAzureプロジェクトにWebロールとして追加します。

この方法はテンプレートが追加されても既存のASP.NET MVC 3プロジェクトをAzure化するのに活用できます。

3ステップ目の参照設定の追加はASP.NET MVC 3関連のDLLがWindows Azureにはまだ入っていないのでデプロイ対象とするためです。

17

このあたりの手順の詳細は「ASP.NET MVC 3をAzureで動かす」にまとめましたのでこちらも合わせて参照してみてください。

ASP.NETはロードバランサ使用前提でつくる

06

WebRoleはロードバランサで負荷分散される

07

なぜセッション情報が必要?

08

欲しいときに依頼すればいい

09

ASP.NET MVC 3

ASP.NET MVC 3 - プロジェクト構成

10

ASP.NET MVC 3 - 処理の流れ

11

ステートレスでビューレスなASP.NET MVC 3

12

13

サンプルソリューションは2部構成

14

今回のサンプルではWindows Azureアプリが動いているところにWindows Phone 7アプリがつなぎに行くという連携になるため1つのソリューションでは同時に動かすことができないので、Windwos Phone 7アプリのソリューションとWindows Azureアプリのソリューションの2部構成にしています。

JsonValueProviderFactory

ASP.NET MVC 3では命名規約ベースで各クラスを紐づけます。

例えば、URL上で「Auth」と指定されたときに呼び出されるコントローラは、AuthControllerクラスとして定義されているものであり、それに対応するモデルはAuthModelsクラス(データアクセス部分はAuthServiceクラス)になります。

Controller - AuthController
Public Class AuthController
    Inherits System.Web.Mvc.Controller

    Public Property AuthService() As IAuthService

    Protected Overrides Sub Initialize(ByVal requestContext As RequestContext)
        If AuthService Is Nothing Then
            AuthService = New AuthService
        End If
        MyBase.Initialize(requestContext)
    End Sub
    '
    ' GET: /Auth
    Function Check(ByVal userID As String, ByVal password As String) As JsonResult
        Return Json((New AuthService).Auth(userID, password), JsonRequestBehavior.AllowGet)
    End Function

End Class

コントローラーでは対応するモデルに含まれているServiceをプロパティとして公開しておきます。

このようにしておけば単体テストを行うときにプロパティにMockクラスを指定することでSQL AzureやSQL Serverを使わずに、また、テストに必要なデータを維持管理することなくMockに期待する値を定義しておくだけでテストが可能だからです。

Model - AuthModels
Imports System.ComponentModel.DataAnnotations

Public Interface IAuthService
    Function Auth(ByVal userName As String,
                  ByVal password As String) As List(Of TAuth)
End Interface

Public Class AuthService
    Implements IAuthService

    Public Function Auth(userID As String,
                         password As String) _
                     As System.Collections.Generic.List(Of TAuth) _
                     Implements IAuthService.Auth
        Dim returnValue As New List(Of TAuth)

        Using _cn As New SqlClient.SqlConnection
            Try
                _cn.ConnectionString = String.Format(GetEnviroment.GetSettings("Connection"),
                                                     userID,
                                                     password)
                _cn.Open()
                returnValue.Add(New TAuth(True, "OK"))
            Catch ex As Exception
                returnValue.Add(New TAuth(False, ex.Message))
            End Try
        End Using
        Return returnValue
    End Function
End Class

Public Class TAuth
    Public Sub New(ByVal isOK As Boolean, ByVal message As String)
        Me.IsOK = isOK
        Me.Message = message
    End Sub
    <Required()>
    Public Property IsOK As Boolean
    <Required()>
    Public Property Message As String
End Class

今回の構成ではSQL Azure (開発環境時はSQL Server Express Edition)からのデータ取得中心で画面表示などがないため、AuthModels.vbファイルの中にはAuthModelsクラスはありません。

データの取得
Controller - TitlesController
Public Class TitlesController
    Inherits System.Web.Mvc.Controller

    Public Property TitlesService() As ITitlesService

    Protected Overrides Sub Initialize(ByVal requestContext As RequestContext)
        If TitlesService Is Nothing Then
            TitlesService = New TitlesService
        End If
        MyBase.Initialize(requestContext)
    End Sub

    '
    ' GET: /Titles
    Function Index(ByVal userID As String, ByVal password As String) As JsonResult
        Return Json((New TitlesService).GetTitles(userID, password), JsonRequestBehavior.AllowGet)
    End Function

End Class
Model - TitlesModels
Imports System
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

Public Interface ITitlesService
    Function GetTitles(ByVal userName As String,
                       ByVal password As String) As List(Of TTitlesList)
End Interface

Public Class TitlesService
    Implements ITitlesService

    Public Function GetTitles(userID As String,
                              password As String) _
                     As System.Collections.Generic.List(Of TTitlesList) _
                     Implements ITitlesService.GetTitles
        Dim returnValue As New List(Of TTitlesList)

        Using _cn As New SqlClient.SqlConnection
            Try
                _cn.ConnectionString = String.Format(GetEnviroment.GetSettings("Connection"),
                                                     userID,
                                                     password)
                _cn.Open()
                Using _cmd As New SqlClient.SqlCommand
                    Dim _dr As SqlClient.SqlDataReader
                    _cmd.Connection = _cn
                    _cmd.CommandText = "SELECT * FROM Titles ORDER BY title"
                    _dr = _cmd.ExecuteReader
                    Do While _dr.Read
                        returnValue.Add(New TTitlesList(_dr.Item("title_id").ToString,
                                                        _dr.Item("title").ToString,
                                                        CType(IIf(IsDBNull(_dr.Item("price")), Nothing, _dr.Item("price")), Decimal?),
                                                        CType(IIf(IsDBNull(_dr.Item("pubdate")), Nothing, _dr.Item("pubdate")), Date?),
                                                        _dr.Item("notes").ToString))
                    Loop
                    _dr.Close()
                End Using
            Catch ex As Exception
                returnValue.Add(New TTitlesList(ex.Message))
            End Try
        End Using
        Return returnValue
    End Function
End Class

Public Class TTitlesList
    Public Sub New(ByVal Title_id As String, ByVal title As String,
                   ByVal price As Decimal?, ByVal pubdate As Date?, ByVal notes As String)
        Me.Title_id = Title_id
        Me.Title = title
        Me.Price = price
        Me.Pubdate = pubdate
        Me.Notes = notes
    End Sub
    Public Sub New(ByVal message As String)
        Me.Notes = message
    End Sub
    <Required()>
    Public Property Title_id As String
    <Required()>
    Public Property Title As String
    <Required()>
    Public Property Price As Nullable(Of Decimal)
    <Required()>
    Public Property Pubdate As Nullable(Of Date)
    <Required()>
    Public Property Notes As String
End Class
Deploy Windows Azure

18

Windows Azure Portal

Windows Phone 7

JSONを使うWindoss Phone 7アプリ

16

Windows Phone 7の実行環境はSilverlight 3をベースにしています。そのためSilverlight 3でのXAMLの知識などが非常に役に立ちます。

かんなりよくできていてお気に入りの環境なのですが、残念な事にJsonでデータを取得したときに便利なJsonSerializerがありません。

そこでcodeplexからService4u2をダウンロードしてきてそれを活用しています。

ログイン
Private WithEvents AuthService As New AuthService

''' Service4u2
Friend Function IsAuthOK(ByVal userID As String,
                         ByVal password As String,
                         ByVal server As String) As Boolean
    AuthService.Check(userID, password, server)
    Return True
End Function

Private Sub AuthService_GotError(ByVal sender As Object,
                                 ByVal e As Service4u2.Common.EventArgs(Of System.Exception)) _
                             Handles AuthService.GotError, TitlesService.GotError
    MessageBox.Show(e.Argument.Message)
End Sub

Private Sub AuthService_GotResult(ByVal sender As Object,
                                  ByVal e As Service4u2.Common.EventArgs(Of List(Of TAuth))) _
                              Handles AuthService.GotResult
    Dim jsonData As List(Of TAuth) = CType(e.Argument, List(Of TAuth))
    If jsonData.Count > 0 AndAlso jsonData(0).IsOK Then
        Me.Setting_Panel.Visibility = True
        If jsonData(0).Message.Length > 0 Then
            Me.Setting_Panel.Visibility = True
            Me.Cursor = Cursors.Wait
            TitlesService.Index(Me.UserID_TextBox.Text,
                                Me.Password_TextBox.Password,
                                Me.Server_TextBox.Text)
        Else
            MessageBox.Show("データ取得エラー",
                                Me.ApplicationTitle.Content,
                                MessageBoxButton.OK)
        End If
    Else
        MessageBox.Show(jsonData(0).Message,
                        Me.ApplicationTitle.Content,
                        MessageBoxButton.OK)
    End If
End Sub
一覧取得
Private WithEvents TitlesService As New TitlesService

Private Sub TitlesService_GotResult(ByVal sender As Object,
                                    ByVal e As Service4u2.Common.EventArgs(Of List(Of TTitles))) _
                              Handles TitlesService.GotResult
    Dim jsonData As List(Of TTitles) = CType(e.Argument, List(Of TTitles))
    If jsonData.Count > 0 Then
        If jsonData(0).Title_id.Length > 0 Then
            Me.Titles_ListBox.Visibility = False
            Me.Titles_ListBox.ItemsSource = jsonData
            Me.Cursor = Cursors.None
        Else
            MessageBox.Show(jsonData(0).Notes,
                            Me.ApplicationTitle.Content,
                            MessageBoxButton.OK)
        End If
    Else
        MessageBox.Show("データ取得エラー",
                        Me.ApplicationTitle.Content,
                        MessageBoxButton.OK)
    End If
End Sub
実機への配置

Windows Phone 7実機へのアプリの配置手順は簡単に表すと次のようになります。

  1. Windows Phone Developer Registrationによる開発環境への実機登録(初回のみ)
  2. 実機をUSBで開発環境に接続しZuneの起動を確認
  3. Visual Studioを起動して該当アプリのプロジェクトを読み込む
  4. 実機が初期画面のタイル表意地になっていることを確認
  5. [ビルド]-[配置]メニューを選択して実機にアプリを転送

実行環境での確認

実行環境の確認はWP7側とAzure側の両方を一度に確認するまえにステップを踏んだ方が問題の切り分けがしやすいです。

  1. WP7 Emulator + Azure Compute Emulator + SQL Server Express
  2. WP7 Emulator + Azure Compute Emulator + 【SQL Azure】
  3. WP7 Emulator +  【Windows Azure - Webロール】【SQL Azure】
  4.  【Windows Phone 7】【Windows Azure - Webロール】【SQL Azure】

COPYRIGHT (C) 2008 初音玲 All rights reserved. / Running .NET Framework 4.0.30319.42000