使ってみよう! Windows Live SDK/API

第17回 Windows Live Application Based Storage API(2)

この記事を読むのに必要な時間:およそ 14 分

フォルダの作成

フォルダの作成はPOSTメソッドを使います。リソースパスにはフォルダを作成する場所を示すコレクション(Items)を指定します。作成するフォルダの名前を指定するにはPOSTデータにAtomプロトコルによる<entry>要素を格納します。<entry>要素の書式は次のようになります。

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:LP="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:LivePhotos="http://dev.live.com/photos" LP:type="Folder">
    <category scheme="http://dev.live.com/AppStorage/scheme" term="Folder" label="Folder" />
    <title>[フォルダ名]</title>
</entry>

<title>要素にフォルダ名を指定します。このとき日本語は使用できません。もともとユーザーに直接見せるものではないので不便はそうありませんが,指定したい場合はURLエンコードするなどしてアプリケーション側での対応が必要です。

フォルダに成功した場合はHTTPステータスコード201 (Created)が応答されます。

それでは,フォルダを作成するメソッドを作ります。コードは以下のとおりです。リソースパスのほかにファイル名を引数に受け取るようにしています。またフォルダ・ファイル情報一覧を取得したRetrieveResourceメソッドと同じようにXmlDocumentを返すようにしています。

Protected Function CreateFolder(ByVal path As String, ByVal folderName As String) As XmlDocument
    Dim document As New XmlDocument
    Dim request As HttpWebRequest = CreatedNewRequest(path, "POST")

    Dim sb As New StringBuilder
    sb.Append("<entry xmlns=""http://www.w3.org/2005/Atom"" xmlns:LP=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" xmlns:LivePhotos=""http://dev.live.com/photos"" LP:type=""Folder"">")
    sb.Append("<category scheme=""http://dev.live.com/AppStorage/scheme"" term=""Folder"" label=""Folder"" />")
    sb.Append("<title>" & folderName & "</title>")
    sb.Append("</entry>")

    Dim buffer() As Byte = System.Text.Encoding.ASCII.GetBytes(sb.ToString)
    request.ContentType = "application/atom+xml"
    request.ContentLength = buffer.Length

    Dim stream As System.IO.Stream = request.GetRequestStream
    stream.Write(buffer, 0, buffer.Length)
    Try
        Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse)
            document.InnerXml = "<response>" & response.StatusCode & "</response>"
        End Using
        Return document

    Catch webEx As WebException
        document.InnerXml = "<exception>" & webEx.Message & "</exception>"
        Return document
    End Try
End Function

成功した場合は<response>要素にその内容を返すようにしていますが,今回のアプリケーションでは利用していません。また同じく今回は利用しませんでしたが,次のようにレスポンスのLocationヘッダを参照すると新しく作成したフォルダのパスがわかります。

Dim location As String = response.Headers(HttpResponseHeader.Location)

Createボタンをクリックしたときに,このメソッドを呼び出すようにします。CreateButtonのClickイベント処理を次のように記述します。

Protected Sub CreateButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateButton.Click
    If ResourceTreeView.CheckedNodes.Count <> 1 OrElse _
       Not ResourceTreeView.CheckedNodes(0).Value.EndsWith("/Items") Then
        MessageLiteral.Text = "フォルダをひとつチェックしてください。"
        Exit Sub
    End If

    Dim document As XmlDocument = CreateFolder(ResourceTreeView.CheckedNodes(0).Value, FolderNameTextBox.Text)
    If document.SelectNodes("/exception").Count > 0 Then
        MessageLiteral.Text = document.SelectNodes("/exception").Item(0).InnerText
    Else
        ' フォルダ作成に成功した場合はそのフォルダが含まれるツリーノードを表示
        ResourceTreeView.CheckedNodes(0).Select()
        ResourceTreeView_SelectedNodeChanged(Me, New EventArgs)
    End If
End Sub

フォルダを作成する場所の指定はツリーノードのチェックボックスを利用します。示したコードではフォルダを示すノードがひとつだけチェックされているかをまず確認しています。フォルダを示すノードかどうかはValueプロパティに設定したリソースパスの末尾をみて判別しています。フォルダ名はFolderNameTextBox.Textの値を使用します。

フォルダ名の変更

作成したフォルダ名を変更するにはPUTメソッドを使います。リクエスト方法は,フォルダ作成と同様に<entry>要素をPOSTデータに指定します。応答は成功した場合,ステータスコード204(No Content)が返ります。

リクエストするリソースのパスは名前を変更するフォルダへのパスを指定し,POSTデータの<title>属性には変更後のフォルダ名を指定します。

フォルダ名を変更するメソッドのコードは次のようになります。

Protected Function RenameFolder(ByVal path As String, ByVal folderName As String) As XmlDocument
    Dim document As New XmlDocument
    Dim request As HttpWebRequest = CreatedNewRequest(path, "PUT")

    '(以下 CreateFolderメソッドと同じ)

End Function

このメソッドをRenameボタンのClickイベントから呼び出しましょう。

Protected Sub RenameButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RenameButton.Click
        If ResourceTreeView.CheckedNodes.Count <> 1 Then
            MessageLiteral.Text = "フォルダまたはファイルををひとつチェックしてください。"
            Exit Sub
        End If


        ' アイテムを示すパスに変換(末尾の/Itemsなど部分を削除)
        Dim value As String = ResourceTreeView.CheckedNodes(0).Value
        Dim path As String = value.Substring(0, value.LastIndexOf("/"))

        Dim document As XmlDocument = RenameFolder(path, FolderNameTextBox.Text)
        If document.SelectNodes("/exception").Count > 0 Then
            MessageLiteral.Text = document.SelectNodes("/exception").Item(0).InnerText
        Else
            ResourceTreeView.CheckedNodes(0).Parent.Select()
            ResourceTreeView_SelectedNodeChanged(Me, New EventArgs)
        End If
End Sub

リソースへのパスはコレクションではなくフォルダを表すアイテムへのパスを指定する必要があります。TreeNode.Valueプロパティに指定していた値はコレクションへのノードパスまたはバイナリデータを示すものでしたので,末尾の「/Items」「/$value」を削除してからメソッドに渡しています。

ちなみにApplication Based Storage APIではファイル名の変更はできません。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp