本記事の対象APIは既にサポートされていません。記事は参考程度にご利用ください。
アルバムとフォトの編集
前回はWindows Live Photo APIを利用した簡単なWebアプリケーションを作成しました。そのアプリケーションでは以下の読み取りに関する内容を実装しました。
- アルバム・
フォト・ フォトタイプの一覧取得 - フォトバイナリデータ取得
今回は、
- アルバムの作成
- フォトのアップロード
- アルバム・
フォトの名前 (タイトル) 変更 - アルバム・
フォトの削除
作成するWebアプリケーションを図1に示します。

あまり良いUIではありませんが、
リクエストとレスポンス
アルバムおよびフォト情報の取得やフォトのダウンロード時には、
最初に今回のコードで共通で利用するメソッドを作成しておきます。Default.
Protected Function CreatedRequest(ByVal path As String, Optional ByVal method As String = "GET") As HttpWebRequest
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(path), HttpWebRequest)
request.Method = method
request.Headers(HttpRequestHeader.Authorization) = String.Format("DelegatedToken dt=""{0}""", Me.DelegateionToken)
Return request
End Function
Live委任認証用のヘッダもここで追加しています。
続いてLiveサービスからのレスポンスを取得する部分もメソッドとして作成しておきましょう。
前回はXML文書やバイナリデータを取得して何かしらの処理をしていましたが、
ここではレスポンス取得するメソッドを次のように作成しました。
Protected Function GetResponse(ByVal request As HttpWebRequest) As HttpStatusCode
Try
Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse)
Return response.StatusCode
End Using
Catch webEx As WebException
Return DirectCast(webEx.Response, HttpWebResponse).StatusCode
End Try
End Function
HttpWebRequestオブジェクトを引数として渡し、
アルバム作成およびフォトのアップロードに成功した場合、
Protected Function GetResponse(ByVal request As HttpWebRequest, ByRef location As String) As HttpStatusCode
Try
location = ""
Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse)
location = response.Headers(HttpResponseHeader.Location)
Return response.StatusCode
End Using
Catch webEx As WebException
Return DirectCast(webEx.Response, HttpWebResponse).StatusCode
End Try
End Function
参照渡しによりLocationヘッダの値を返すようにしています。
アルバムの作成
最初に新しいアルバムを作成してみましょう。アルバム作成時に指定するリソースパスは、
https://cumulus.services.live.com/@C@[LID]/AtomSpacesPhotos/Folders
そしてPOSTメソッドにより以下のXML文書を送信します。
<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>
Atomプロトコルの<entry>要素になっています。<title>要素に新しく作成するアルバム名を指定しています。
以上のリクエストを行うと、
ここまでをアプリケーションに実装します。まず、
<fieldset>
<legend>アルバムの作成</legend>
<label>アルバム名: </label>
<asp:TextBox ID="NewAlbumNameTextBox" runat="server"></asp:TextBox>
<asp:Button ID="CreateButton" runat="server" Text="作成" />
</fieldset>
作成ボタンがクリックされたときのコードは、
Protected Sub CreateButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateButton.Click
' リクエストの作成
Dim request As HttpWebRequest = CreatedRequest("https://cumulus.services.live.com/@C@" & Me.LocationId & "/AtomSpacesPhotos/Folders", "POST")
' <entry>要素の作成
Dim entry As String = _
"<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>" & HttpUtility.HtmlEncode(NewAlbumNameTextBox.Text) & "</title>" & _
"</entry>"
' リクエストの各種設定
Dim buffer() As Byte = System.Text.Encoding.UTF8.GetBytes(entry)
request.ContentType = "application/atom+xml"
request.ContentLength = buffer.Length
Dim stream As System.IO.Stream = request.GetRequestStream
stream.Write(buffer, 0, buffer.Length)
' レスポンスの取得
Dim location As String = "" ' 作成されたアルバムのリソースパス URL
Dim status As HttpStatusCode = GetResponse(request, location)
If status = HttpStatusCode.Created Then
ListAlbums() ' アルバム一覧の表示 (前回のコード)
Else
' (エラー処理)
End If
End Sub
CreateRequestメソッドを呼び出しリクエストを作成した後、
レスポンスの取得では、
フォトのアップロード
フォトのアップロードは、
リソースパスには、
このほか、
それでは処理を実装しましょう。Webページには、
<fieldset>
<legend>フォトのアップロード</legend>
<label>フォト名: </label>
<asp:TextBox ID="NewPhotoNameTextBox" runat="server"></asp:TextBox>
<br />
<label>ファイル: </label>
<asp:FileUpload ID="PhotoFileUpload" runat="server" />
<asp:Button ID="UploadButton" runat="server" Text="アップロード" />
</fieldset>
アップロードボタンをクリックしたときの処理は次のようになります。
Protected Sub UploadButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles UploadButton.Click
' アルバムリストボックスから選択されている ListItem 取得
Dim item As ListItem = AlbumListBox.SelectedItem
If item Is Nothing Then
Exit Sub ' 選択されていない場合は処理を終了
End If
' リクエストの作成 (ListItem.Value には、フォト一覧のリソースパスが格納されている)
Dim request As HttpWebRequest = CreatedRequest(item.Value, "POST")
' アルバム名を指定
request.Headers.Add("slug", HttpUtility.UrlEncode(NewPhotoNameTextBox.Text))
' ContentType を指定
request.ContentType = PhotoFileUpload.PostedFile.ContentType.Replace("/pjpeg", "/jpeg")
' バイナリデータの指定
Dim buffer() As Byte = PhotoFileUpload.FileBytes
request.ContentLength = buffer.Length
Dim stream As System.IO.Stream = request.GetRequestStream
stream.Write(buffer, 0, buffer.Length)
' レスポンスの取得
Dim location ADims String = "" ' アップロードしたフォトのリソースパス URL
Dim status As HttpStatusCode = GetResponse(request, location)
If status = HttpStatusCode.Created Then
ListPhotos(item.Value) ' フォト一覧の表示 (前回のコード)
Else
' (エラー処理)
End If
End Sub
フォトを追加する先のアルバムの選択は、
APIの制限・仕様
ここまででアルバムの作成とフォトのアップロードができるようになりました。実際に実行して確認してみましょう

実行して試す際の留意事項およびAPIの制限と思われる点をここで述べておきます。
日本語・特殊文字
アルバム名・
アルバムのアクセス制限
Live Spacesからアルバムを編集すると、
フォトタイプ
フォトにはサムネイル用やWeb用といったタイプがあり、
アルバム・フォトの名前変更
アルバムとフォトの名前
指定するリソースパスと送信する<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>
フォト名の変更
フォト名を変更する際に指定するリソースパスは、
<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" xmlns:Live="LiveAtomBase:" LP:type="Photo">
<category scheme="http://dev.live.com/photos/scheme" term="Photo" label="Photo" />
<title>[フォト名]</title>
</entry>
コードの記述
それでは名前変更の処理を記述しましょう。Webページには、
<fieldset>
<legend>選択されているアルバムまたはフォトの名前変更</legend>
<label>新しい名前: </label>
<asp:TextBox ID="NewNameTextBox" runat="server"></asp:TextBox>
<asp:Button ID="AlbumRenameButton" runat="server" Text="アルバム名変更" />
<asp:Button ID="PhotoRenameButton" runat="server" Text="フォト名変更" />
</fieldset>
アルバムの名前変更の処理を記述します。Clickイベントは次のように処理します。
Protected Sub AlbumRenameButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AlbumRenameButton.Click
' アルバムリストボックスから選択されている ListItem 取得
Dim item As ListItem = AlbumListBox.SelectedItem
If item Is Nothing Then
Exit Sub ' 選択されていない場合は処理を終了
End If
' リクエストの作成
Dim request As HttpWebRequest = CreatedRequest(item.Value.Replace("/Photos", ""), "PUT")
' <entry>要素の作成
Dim entry As String = _
"<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>" & HttpUtility.HtmlEncode(NewNameTextBox.Text) & "</title>" & _
"</entry>"
' リクエストの各種設定
Dim buffer() As Byte = System.Text.Encoding.UTF8.GetBytes(entry)
request.ContentType = "application/atom+xml"
request.ContentLength = buffer.Length
Dim stream As System.IO.Stream = request.GetRequestStream
stream.Write(buffer, 0, buffer.Length)
' レスポンスの取得
Dim status As HttpStatusCode = GetResponse(request)
If status = HttpStatusCode.NoContent Then
ListAlbums() ' アルバム一覧の表示 (前回のコード)
Else
' (エラー処理)
End If
End Sub
アルバムの選択はアルバム一覧のリストボックスを利用しています。これはフォトのアップロードの処理と同じです。ただし、
レスポンスの取得では、
続いてフォト名変更のコードは次のようになります。
Protected Sub PhotoRenameButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PhotoRenameButton.Click
' フォトリストボックスから選択されている ListItem 取得
Dim item As ListItem = PhotoListBox.SelectedItem
If item Is Nothing Then
Exit Sub ' 選択されていない場合は処理を終了
End If
' リクエストの各種設定
Dim request As HttpWebRequest = CreatedRequest(item.Value.Replace("/ImageStreams", ""), "PUT")
' <entry>要素の作成
Dim entry As String = _
"<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"" xmlns:Live=""LiveAtomBase:"" LP:type=""Photo"">" & _
"<category scheme=""http://dev.live.com/photos/scheme"" term=""Photo"" label=""Photo"" />" & _
"<title>" & HttpUtility.HtmlEncode(NewNameTextBox.Text) & "</title>" & _
"</entry>"
' リクエストの各種設定
Dim buffer() As Byte = System.Text.Encoding.UTF8.GetBytes(entry)
request.ContentType = "application/atom+xml"
request.ContentLength = buffer.Length
Dim stream As System.IO.Stream = request.GetRequestStream
stream.Write(buffer, 0, buffer.Length)
' レスポンスの取得
Dim status As HttpStatusCode = GetResponse(request)
If status = HttpStatusCode.NoContent Then
' フォト一覧の表示 (前回のコード)
ListPhotos(AlbumListBox.SelectedItem.Value)
Else
' (エラー処理)
Label1.Text = status.ToString
End If
End Sub
アルバム名変更のときとほぼ同様ですが、
名前の変更は、
アルバム・フォトの削除
最後はアルバムとフォトの削除についてです。削除する場合は、
ここまでを順に実装していれば、
<fieldset>
<legend>選択されているアルバムまたはフォトの削除</legend>
<asp:Button ID="AlbumDeleteButton" runat="server" Text="アルバムの削除" />
<asp:Button ID="PhotoDeleteButton" runat="server" Text="フォトの削除" />
</fieldset>
アルバムの削除ボタンをクリックしたときの処理は次のように記述します。
Protected Sub AlbumDeleteButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AlbumDeleteButton.Click
' アルバムリストボックスから選択されている ListItem 取得
Dim item As ListItem = AlbumListBox.SelectedItem
If item Is Nothing Then
Exit Sub ' 選択されていない場合は処理を終了
End If
' リクエストの作成
Dim request As HttpWebRequest = CreatedRequest(item.Value.Replace("/Photos", ""), "DELETE")
' レスポンスの取得
Dim status As HttpStatusCode = GetResponse(request)
If status = HttpStatusCode.NoContent Then
ListAlbums() ' アルバム一覧の表示 (前回のコード)
Else
' (エラー処理)
End If
End Sub
送信するバイナリデータがないためコードが短いです。パスの指定部分は名前変更のときと同じListItem.
フォトの削除ボタンをクリックしたときの処理は以下のようになります。
Protected Sub PhotoDeleteButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PhotoDeleteButton.Click
' フォトリストボックスから選択されている ListItem 取得
Dim item As ListItem = PhotoListBox.SelectedItem
If item Is Nothing Then
Exit Sub ' 選択されていない場合は処理を終了
End If
' リクエストの作成
Dim request As HttpWebRequest = CreatedRequest(item.Value.Replace("/ImageStreams", ""), "DELETE")
' レスポンスの取得
Dim status As HttpStatusCode = GetResponse(request)
If status = HttpStatusCode.NoContent Then
' フォト一覧の表示 (前回のコード)
ListPhotos(AlbumListBox.SelectedItem.Value)
Else
' (エラー処理)
End If
End Sub
以上で今回作成するWebアプリケーションは完成です。
おわりに
今回でLive Photo ATOM APIについては一区切りとして終了です。いかがでしたでしょうか。以前に本連載で紹介したPhoto APIと同じLiveユーザーデータAPIに属するLive Application Based Storage APIと比較すると、