This is my first article in a series describing the Google Photos API in ASP.NET. I’ll explain how you can easily pull a list of the web photo albums from the popular
Google Picasa service. Before we start I assume that you have your own Google account with activated Picasa service and a couple of photo albums.
Google Data API
Google Photos API can be easily consumed by .NET library for the Google Data Api. After you download and install the Google Data Api library on your computer, you will find everything that you need in the folder \Program Files\Google\Google Data API SDK. You will need to add the following assemblies to your project as project references: Google.GData.Client.dll, Google.GData.Extensions.dll, Google.GData.Photos.dll.
Authentication
My colleague has a nice article that explains two ways to connect to the Google Docs account: Using Google Docs API in ASP.NET . The first approach is to just ask user for his/her credentials, and the alternative is to use OAuth 2.0 with a stored refresh token or OAuth 1.0a with a stored access token. In this article we will ask user for the credentials, but most real-life scenarios will use OAuth infrastructure.
Here is the markup code for the authentication form:
<
asp:PlaceHolder
ID
=
"phGoogleConect"
runat
=
"server"
>
<
fieldset
>
<
asp:ValidationSummary
ID
=
"validationSummary"
runat
=
"server"
CssClass
=
"failureNotification"
ValidationGroup
=
"PicasaValidationGroup"
/>
<
legend
>Connect to Picasa Web Albums</
legend
>
<
p
>
<
asp:Label
ID
=
"lblUsername"
runat
=
"server"
AssociatedControlID
=
"txtUsername"
>Username:</
asp:Label
>
<
asp:TextBox
ID
=
"txtUsername"
runat
=
"server"
CssClass
=
"textEntry"
></
asp:TextBox
>
<
asp:RequiredFieldValidator
ID
=
"rfUsername"
runat
=
"server"
ControlToValidate
=
"txtUsername"
CssClass
=
"failureNotification"
ErrorMessage
=
"Username is required."
ToolTip
=
"Username is required."
ValidationGroup
=
"PicasaValidationGroup"
>*</
asp:RequiredFieldValidator
>
</
p
>
<
p
>
<
asp:Label
ID
=
"lblPassword"
runat
=
"server"
AssociatedControlID
=
"txtPassword"
>Password:</
asp:Label
>
<
asp:TextBox
ID
=
"txtPassword"
runat
=
"server"
CssClass
=
"passwordEntry"
TextMode
=
"Password"
></
asp:TextBox
>
<
asp:RequiredFieldValidator
ID
=
"rfPassword"
runat
=
"server"
ControlToValidate
=
"txtPassword"
CssClass
=
"failureNotification"
ErrorMessage
=
"Password is required."
ToolTip
=
"Password is required."
ValidationGroup
=
"PicasaValidationGroup"
>*</
asp:RequiredFieldValidator
>
</
p
>
<
asp:CustomValidator
ID
=
"cvCredentials"
runat
=
"server"
ValidationGroup
=
"PicasaValidationGroup"
></
asp:CustomValidator
>
</
fieldset
>
<
p
class
=
"submitButton"
>
<
asp:Button
ID
=
"btnConnect"
runat
=
"server"
CommandName
=
"Login"
Text
=
"Connect"
ValidationGroup
=
"PicasaValidationGroup"
/>
</
p
>
</
asp:PlaceHolder
>
The code for authentication in code-behind has been mixed with code for retrieving web albums:
public
string
Username
{
get
{
return
ViewState[
"Username"
] !=
null
? Convert.ToString(ViewState[
"Username"
]) : String.Empty;
}
set
{
ViewState[
"Username"
] = value;
}
}
public
string
Password
{
get
{
return
ViewState[
"Password"
] !=
null
? Convert.ToString(ViewState[
"Password"
]) : String.Empty;
}
set
{
ViewState[
"Password"
] = value;
}
}
public
string
AuthToken
{
get
{
return
ViewState[
"AuthToken"
] !=
null
? Convert.ToString(ViewState[
"AuthToken"
]) : String.Empty;
}
set
{
ViewState[
"AuthToken"
] = value;
}
}
...
private
void
BindAlbums()
{
try
{
AlbumQuery query =
new
AlbumQuery();
query.Uri =
new
Uri(PicasaQuery.CreatePicasaUri(
this
.Username));
picasaService.setUserCredentials(
this
.Username,
this
.Password);
AuthToken = picasaService.QueryClientLoginToken();
PicasaFeed picasaFeed = picasaService.Query(query);
if
(picasaFeed !=
null
)
{
dlAlbums.DataSource = picasaFeed.Entries;
dlAlbums.DataBind();
}
phPicasaAlbums.Visible =
true
;
phGoogleConect.Visible =
false
;
}
catch
(Exception ex)
{
cvCredentials.ErrorMessage = ex.Message;
cvCredentials.IsValid =
false
;
}
}
Retrieving Picasa web albums
After successful authentication we will pull a list of all (public and private) web albums for the current user. If you skip the authentication you can pull any public list of the web albums by specifying the album owner's username.
Here is the screen shot of our target UI in which we have two sections: first section is showing the list of web albums and the second section is displaying a list of photos from the selected album:

Here is the markup code for displaying the retrieved list of web albums.
<
asp:PlaceHolder
ID
=
"phPicasaAlbums"
runat
=
"server"
>
<
fieldset
>
<
p
>
<
asp:Label
ID
=
"lblAlbums"
runat
=
"server"
AssociatedControlID
=
"dlAlbums"
><
h3
>Web Albums:</
h3
></
asp:Label
>
<
asp:DataList
ID
=
"dlAlbums"
runat
=
"server"
RepeatDirection
=
"Horizontal"
RepeatColumns
=
"5"
>
<
SeparatorTemplate
><
br
/><
br
/></
SeparatorTemplate
>
<
SelectedItemStyle
BackColor
=
"Aquamarine"
/>
<
SelectedItemTemplate
>
<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Title.Text %><
br
/>
<
asp:LinkButton
ID
=
"btnAlbum"
runat
=
"server"
CommandArgument="<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).GetPhotoExtensionValue(Google.GData.Photos.GPhotoNameTable.Id) %>" CommandName="select">
<
img
src="<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Media.Thumbnails[0].Url %>" />
</
asp:LinkButton
>
</
SelectedItemTemplate
>
<
ItemTemplate
>
<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Title.Text %><
br
/>
<
asp:LinkButton
ID
=
"btnAlbum"
runat
=
"server"
CommandArgument="<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).GetPhotoExtensionValue(Google.GData.Photos.GPhotoNameTable.Id) %>" CommandName="select">
<
img
src="<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Media.Thumbnails[0].Url %>" />
</
asp:LinkButton
>
</
ItemTemplate
>
</
asp:DataList
>
</
p
>
<
p
>
<
asp:Label
ID
=
"lblPhotos"
runat
=
"server"
AssociatedControlID
=
"dlPhotos"
><
h3
>Photos from selected album:</
h3
></
asp:Label
>
<
asp:DataList
ID
=
"dlPhotos"
runat
=
"server"
RepeatDirection
=
"Horizontal"
RepeatColumns
=
"5"
>
<
SeparatorTemplate
></
SeparatorTemplate
>
<
ItemTemplate
>
<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Title.Text %><
br
/>
<
img
src="<%# ((Google.GData.Photos.PicasaEntry)Container.DataItem).Media.Thumbnails[2].Url %>" />
</
ItemTemplate
>
</
asp:DataList
>
</
p
>
</
fieldset
>
</
asp:PlaceHolder
>
Here we need to create an instance of the PicasaService:
private
PicasaService picasaService =
new
PicasaService(
"Picasa"
);
The code for populating the DataList controls with the list of web albums is shown below. Please note that we need to create an instance of the AlbumQuery and the PicasaUri by passing the owner's username. We also need to set the user credentials and the AuthToken received after the successful login.
private
void
BindAlbums()
{
try
{
AlbumQuery query =
new
AlbumQuery();
query.Uri =
new
Uri(PicasaQuery.CreatePicasaUri(
this
.Username));
picasaService.setUserCredentials(
this
.Username,
this
.Password);
AuthToken = picasaService.QueryClientLoginToken();
PicasaFeed picasaFeed = picasaService.Query(query);
if
(picasaFeed !=
null
)
{
dlAlbums.DataSource = picasaFeed.Entries;
dlAlbums.DataBind();
}
phPicasaAlbums.Visible =
true
;
phGoogleConect.Visible =
false
;
}
catch
(Exception ex)
{
cvCredentials.ErrorMessage = ex.Message;
cvCredentials.IsValid =
false
;
}
}
After this, we can populate the DataList control with the list of photos from the selected album.
void
dlAlbums_ItemCommand(
object
source, DataListCommandEventArgs e)
{
if
(!String.IsNullOrEmpty(AuthToken))
{
PhotoQuery query =
new
PhotoQuery();
SelectedAlbumID = e.CommandArgument.ToString();
query.Uri =
new
Uri(PicasaQuery.CreatePicasaUri(
this
.Username, SelectedAlbumID));
picasaService.SetAuthenticationToken(AuthToken);
PicasaFeed picasaFeed = picasaService.Query(query);
if
(picasaFeed !=
null
&& picasaFeed.Entries.Count > 0)
{
dlPhotos.DataSource = picasaFeed.Entries;
}
dlPhotos.DataBind();
phPicasaAlbums.Visible =
true
;
phGoogleConect.Visible =
false
;
}
}
I have attached a fully functional sample project to this article. In the next article I’ll show how to perform some more advanced tasks on the albums and photos.