(1)MainPage.xaml 2.95KB
<phone:PhoneApplicationPage
x:Class="SkyDrive_Photos_Sample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="WINDOWS LIVE" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="SkyDrive Photos Sample" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="595" HorizontalAlignment="Left" Margin="6,6,0,0" Name="outputText" Text="" VerticalAlignment="Top" Width="444" Visibility="Collapsed" FontSize="28" />
<Button Content="Sign In" Height="72" HorizontalAlignment="Left" Margin="12,6,0,0" Name="signInButton" VerticalAlignment="Top" Width="160" Click="OnSignInButtonClicked" />
<TextBlock Height="112" HorizontalAlignment="Stretch" Margin="9,84,9,0" Name="errorMessage" VerticalAlignment="Top" />
</Grid>
<phone:WebBrowser Name="authorizationBrowser" Grid.RowSpan="2" IsScriptEnabled="True" Visibility="Collapsed" />
<Grid x:Name="loadingGrid" Grid.RowSpan="2" HorizontalAlignment="Stretch" Visibility="Collapsed" Background="#B9000000">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock Height="30" HorizontalAlignment="Center" Name="loadingText" Text="Loading..." VerticalAlignment="Center" Width="441" TextAlignment="Center" />
<ProgressBar Height="4" HorizontalAlignment="Center" Name="loadingProgress" VerticalAlignment="Center" IsIndeterminate="True" HorizontalContentAlignment="Center" Width="400" />
</StackPanel>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
(2)MainPage.xaml.cs 11.35KB
//-----------------------------------------------------------------------
// <copyright file="MainPage.xaml.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace SkyDrive_Photos_Sample
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Windows;
using Microsoft.Phone.Controls;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Windows.Media;
using System.Windows.Media.Imaging;
/// <summary>
/// Used to indicate what data is being returned by a particular HTTP request
/// </summary>
public enum Results{UserInfo, AlbumInfo};
/// <summary>
/// The main landing page.
/// </summary>
public partial class MainPage : PhoneApplicationPage
{
/// <summary>
/// The URI for the OAuth service's Authorize endpoint.
/// </summary>
private static readonly string OAuthAuthorizeUri = "https://oauth.live.com/authorize";
/// <summary>
/// The URI for the API service endpoint.
/// </summary>
private static readonly string ApiServiceUri = "https://apis.live.net/v5.0/";
/// <summary>
/// The applications client ID.
/// </summary>
private static readonly string ClientId = /* insert client ID here - go to http://manage.dev.live.com to get one */ ;
/// <summary>
/// The applications redirect URI (does not need to exist).
/// </summary>
private static readonly string RedirectUri = "https://oauth.live.com/desktop";
/// <summary>
/// Holds the retrieved access token.
/// </summary>
private string accessToken;
/// <summary>
/// The list of scopes.
/// </summary>
private string[] scopes = new string[] { "wl.basic", "wl.photos" };
/// <summary>
/// The resource to request.
/// </summary>
private string user = "me";
/// <summary>
/// The user's album resource
/// </summary>
private string albums = "me/albums";
/// <summary>
/// Initializes a new instance of the <see cref="MainPage"/> class.
/// </summary>
public MainPage()
{
this.InitializeComponent();
}
/// <summary>
/// Override the back key press to prevent application exit when the popup is open.
/// </summary>
/// <param name="e">The event data.</param>
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (this.authorizationBrowser.Visibility == Visibility.Visible)
{
this.CompleteOAuthFlow(false);
e.Cancel = true;
}
else
{
base.OnBackKeyPress(e);
}
}
/// <summary>
/// Launch the OAuth flow.
/// </summary>
private void LaunchOAuthFlow()
{
this.loadingGrid.Visibility = Visibility.Visible;
this.authorizationBrowser.Navigating += this.OnAuthorizationBrowserNavigating;
this.authorizationBrowser.Navigated += this.OnAuthorizationBrowserNavigated;
this.authorizationBrowser.Navigate(this.BuildOAuthUri(this.scopes));
}
/// <summary>
/// Complete the OAuth flow.
/// </summary>
/// <param name="success">Whether the operation was successful.</param>
private void CompleteOAuthFlow(bool success)
{
this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
this.authorizationBrowser.Navigating -= this.OnAuthorizationBrowserNavigating;
this.authorizationBrowser.NavigateToString(String.Empty);
this.authorizationBrowser.Visibility = Visibility.Collapsed;
if (success)
{
this.GetUserData();
this.signInButton.Visibility = Visibility.Collapsed;
}
}
/// <summary>
/// Retrieve the user's information from the API service.
/// </summary>
private void GetUserData()
{
this.loadingGrid.Visibility = Visibility.Visible;
WebClient client = new WebClient();
client.OpenReadCompleted += this.OnClientOpenReadComplete;
client.OpenReadAsync(this.BuildApiUri(this.user), Results.UserInfo);
}
/// <summary>
/// Complete the operation and display the output.
/// </summary>
/// <param name="info">The user information.</param>
private void GetUserDataComplete(UserInfo info)
{
string output = String.Format(
"First Name: {0}\nLast Name: {1}\nLink: {2}\n",
info.FirstName,
info.LastName,
info.Link);
this.outputText.Text = output + this.outputText.Text;
this.loadingGrid.Visibility = Visibility.Collapsed;
this.outputText.Visibility = System.Windows.Visibility.Visible;
}
/// <summary>
/// Complete the operation and display the photo albums
/// </summary>
/// <param name="albums">The user's albums</param>
private void GetAlbumDataComplete(Albums albumList)
{
this.outputText.Text = this.outputText.Text + "\nSkyDrive Albums\n";
foreach (AlbumInfo info in albumList.data)
{
string s = (info.Count == 1 ? String.Empty : "s");
this.outputText.Text += String.Format("{0} ({1} photo{2})\n", info.Name, info.Count, s);
}
}
/// <summary>
/// Build the API service URI.
/// </summary>
/// <param name="path">The relative path requested.</param>
/// <returns>The request URI.</returns>
private Uri BuildApiUri(string path)
{
UriBuilder builder = new UriBuilder(MainPage.ApiServiceUri);
builder.Path += path;
builder.Query = "access_token=" + HttpUtility.UrlEncode(this.accessToken);
return builder.Uri;
}
/// <summary>
/// Build the OAuth URI.
/// </summary>
/// <param name="scopes">The requested scopes.</param>
/// <returns>The OAuth URI.</returns>
private Uri BuildOAuthUri(string[] scopes)
{
List<string> paramList = new List<string>();
paramList.Add("client_id=" + HttpUtility.UrlEncode(MainPage.ClientId));
paramList.Add("scope=" + HttpUtility.UrlEncode(String.Join(" ", scopes)));
paramList.Add("response_type=" + HttpUtility.UrlEncode("token"));
paramList.Add("display=" + HttpUtility.UrlEncode("touch"));
paramList.Add("redirect_uri=" + HttpUtility.UrlEncode(MainPage.RedirectUri));
UriBuilder authorizeUri = new UriBuilder(MainPage.OAuthAuthorizeUri);
authorizeUri.Query = String.Join("&", paramList.ToArray());
return authorizeUri.Uri;
}
/// <summary>
/// Process the URI fragment string.
/// </summary>
/// <param name="fragment">The URI fragment.</param>
/// <returns>The key-value pairs.</returns>
private Dictionary<string, string> ProcessFragments(string fragment)
{
Dictionary<string, string> processedFragments = new Dictionary<string, string>();
if (fragment[0] == '#')
{
fragment = fragment.Substring(1);
}
string[] fragmentParams = fragment.Split('&');
foreach (string fragmentParam in fragmentParams)
{
string[] keyValue = fragmentParam.Split('=');
if (keyValue.Length == 2)
{
processedFragments.Add(keyValue[0], HttpUtility.UrlDecode(keyValue[1]));
}
}
return processedFragments;
}
/// <summary>
/// Handles the click event of the sign in button.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnSignInButtonClicked(object sender, RoutedEventArgs e)
{
this.LaunchOAuthFlow();
}
/// <summary>
/// Handles the navigating event of the OAuth web browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnAuthorizationBrowserNavigated(object sender, NavigationEventArgs e)
{
this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
this.loadingGrid.Visibility = Visibility.Collapsed;
this.authorizationBrowser.Visibility = Visibility.Visible;
}
/// <summary>
/// Handles the navigating event of the OAuth web browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnAuthorizationBrowserNavigating(object sender, NavigatingEventArgs e)
{
Uri uri = e.Uri;
if (uri != null && uri.AbsoluteUri.StartsWith(MainPage.RedirectUri))
{
Dictionary<string, string> fragments = this.ProcessFragments(uri.Fragment);
bool success = fragments.TryGetValue("access_token", out this.accessToken);
e.Cancel = true;
this.CompleteOAuthFlow(success);
}
}
/// <summary>
/// Handles the open read complete event of the <see cref="WebClient"/> object.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnClientOpenReadComplete(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer deserializer;
if (e.UserState.Equals(Results.UserInfo))
{
deserializer = new DataContractJsonSerializer(typeof(UserInfo));
UserInfo userInfo = (UserInfo)deserializer.ReadObject(e.Result);
this.GetUserDataComplete(userInfo);
WebClient client = new WebClient();
client.OpenReadCompleted += this.OnClientOpenReadComplete;
client.OpenReadAsync(this.BuildApiUri(this.albums), Results.AlbumInfo);
}
else if (e.UserState.Equals(Results.AlbumInfo))
{
deserializer = new DataContractJsonSerializer(typeof(Albums));
Albums albumInfo = (Albums)deserializer.ReadObject(e.Result);
this.GetAlbumDataComplete(albumInfo);
}
}
}
}
AlbumInfo.cs 3.02KB
//-----------------------------------------------------------------------
// <copyright file="AlbumInfo.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace SkyDrive_Photos_Sample
{
/// <summary>
/// Represents the user that created the album
/// </summary>
[DataContract]
public class From
{
/// <summary>
/// Gets or sets the name of the user
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the id of the user
/// </summary>
[DataMember(Name = "id")]
public string Id
{
get;
set;
}
}
/// <summary>
/// Represents multiple albums returned in a JSON request
/// </summary>
public class Albums
{
public List<AlbumInfo> data { get; set; }
}
/// <summary>
/// Represents a photo album in SkyDrive.
/// </summary>
[DataContract]
public class AlbumInfo
{
/// <summary>
/// Gets or sets the id of the album
/// </summary>
[DataMember(Name = "id")]
public string Id
{
get;
set;
}
/// <summary>
/// Gets or sets the user who created the album
/// </summary>
[DataMember(Name = "from")]
public From From
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the album
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the description of the album
/// </summary>
[DataMember(Name = "description")]
public string Description
{
get;
set;
}
/// <summary>
/// Gets or sets the number of photos in the album
/// </summary>
[DataMember(Name = "count")]
public int Count
{
get;
set;
}
/// <summary>
/// Gets or sets the link to the album
/// </summary>
[DataMember(Name = "link")]
public string Link
{
get;
set;
}
/// <summary>
/// Gets or sets the type of folder in SkyDrive
/// </summary>
[DataMember(Name = "type")]
public string Type
{
get;
set;
}
/// <summary>
/// Gets or sets the created time of the album
/// </summary>
[DataMember(Name = "created_time")]
public string CreatedTime
{
get;
set;
}
/// <summary>
/// Gets or sets the updated time of the album
/// </summary>
[DataMember(Name = "updated_time")]
public string UpdatedTime
{
get;
set;
}
}
}
UserInfo.cs 1.42KB
//-----------------------------------------------------------------------
// <copyright file="UserInfo.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace SkyDrive_Photos_Sample
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Represents the user info returned by the "me" call.
/// </summary>
[DataContract]
public class UserInfo
{
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "first_name")]
public string FirstName
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "last_name")]
public string LastName
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "link")]
public string Link
{
get;
set;
}
}
}
<phone:PhoneApplicationPage
x:Class="SkyDrive_Photos_Sample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="WINDOWS LIVE" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="SkyDrive Photos Sample" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="595" HorizontalAlignment="Left" Margin="6,6,0,0" Name="outputText" Text="" VerticalAlignment="Top" Width="444" Visibility="Collapsed" FontSize="28" />
<Button Content="Sign In" Height="72" HorizontalAlignment="Left" Margin="12,6,0,0" Name="signInButton" VerticalAlignment="Top" Width="160" Click="OnSignInButtonClicked" />
<TextBlock Height="112" HorizontalAlignment="Stretch" Margin="9,84,9,0" Name="errorMessage" VerticalAlignment="Top" />
</Grid>
<phone:WebBrowser Name="authorizationBrowser" Grid.RowSpan="2" IsScriptEnabled="True" Visibility="Collapsed" />
<Grid x:Name="loadingGrid" Grid.RowSpan="2" HorizontalAlignment="Stretch" Visibility="Collapsed" Background="#B9000000">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock Height="30" HorizontalAlignment="Center" Name="loadingText" Text="Loading..." VerticalAlignment="Center" Width="441" TextAlignment="Center" />
<ProgressBar Height="4" HorizontalAlignment="Center" Name="loadingProgress" VerticalAlignment="Center" IsIndeterminate="True" HorizontalContentAlignment="Center" Width="400" />
</StackPanel>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
(2)MainPage.xaml.cs 11.35KB
//-----------------------------------------------------------------------
// <copyright file="MainPage.xaml.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace SkyDrive_Photos_Sample
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Windows;
using Microsoft.Phone.Controls;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Windows.Media;
using System.Windows.Media.Imaging;
/// <summary>
/// Used to indicate what data is being returned by a particular HTTP request
/// </summary>
public enum Results{UserInfo, AlbumInfo};
/// <summary>
/// The main landing page.
/// </summary>
public partial class MainPage : PhoneApplicationPage
{
/// <summary>
/// The URI for the OAuth service's Authorize endpoint.
/// </summary>
private static readonly string OAuthAuthorizeUri = "https://oauth.live.com/authorize";
/// <summary>
/// The URI for the API service endpoint.
/// </summary>
private static readonly string ApiServiceUri = "https://apis.live.net/v5.0/";
/// <summary>
/// The applications client ID.
/// </summary>
private static readonly string ClientId = /* insert client ID here - go to http://manage.dev.live.com to get one */ ;
/// <summary>
/// The applications redirect URI (does not need to exist).
/// </summary>
private static readonly string RedirectUri = "https://oauth.live.com/desktop";
/// <summary>
/// Holds the retrieved access token.
/// </summary>
private string accessToken;
/// <summary>
/// The list of scopes.
/// </summary>
private string[] scopes = new string[] { "wl.basic", "wl.photos" };
/// <summary>
/// The resource to request.
/// </summary>
private string user = "me";
/// <summary>
/// The user's album resource
/// </summary>
private string albums = "me/albums";
/// <summary>
/// Initializes a new instance of the <see cref="MainPage"/> class.
/// </summary>
public MainPage()
{
this.InitializeComponent();
}
/// <summary>
/// Override the back key press to prevent application exit when the popup is open.
/// </summary>
/// <param name="e">The event data.</param>
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (this.authorizationBrowser.Visibility == Visibility.Visible)
{
this.CompleteOAuthFlow(false);
e.Cancel = true;
}
else
{
base.OnBackKeyPress(e);
}
}
/// <summary>
/// Launch the OAuth flow.
/// </summary>
private void LaunchOAuthFlow()
{
this.loadingGrid.Visibility = Visibility.Visible;
this.authorizationBrowser.Navigating += this.OnAuthorizationBrowserNavigating;
this.authorizationBrowser.Navigated += this.OnAuthorizationBrowserNavigated;
this.authorizationBrowser.Navigate(this.BuildOAuthUri(this.scopes));
}
/// <summary>
/// Complete the OAuth flow.
/// </summary>
/// <param name="success">Whether the operation was successful.</param>
private void CompleteOAuthFlow(bool success)
{
this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
this.authorizationBrowser.Navigating -= this.OnAuthorizationBrowserNavigating;
this.authorizationBrowser.NavigateToString(String.Empty);
this.authorizationBrowser.Visibility = Visibility.Collapsed;
if (success)
{
this.GetUserData();
this.signInButton.Visibility = Visibility.Collapsed;
}
}
/// <summary>
/// Retrieve the user's information from the API service.
/// </summary>
private void GetUserData()
{
this.loadingGrid.Visibility = Visibility.Visible;
WebClient client = new WebClient();
client.OpenReadCompleted += this.OnClientOpenReadComplete;
client.OpenReadAsync(this.BuildApiUri(this.user), Results.UserInfo);
}
/// <summary>
/// Complete the operation and display the output.
/// </summary>
/// <param name="info">The user information.</param>
private void GetUserDataComplete(UserInfo info)
{
string output = String.Format(
"First Name: {0}\nLast Name: {1}\nLink: {2}\n",
info.FirstName,
info.LastName,
info.Link);
this.outputText.Text = output + this.outputText.Text;
this.loadingGrid.Visibility = Visibility.Collapsed;
this.outputText.Visibility = System.Windows.Visibility.Visible;
}
/// <summary>
/// Complete the operation and display the photo albums
/// </summary>
/// <param name="albums">The user's albums</param>
private void GetAlbumDataComplete(Albums albumList)
{
this.outputText.Text = this.outputText.Text + "\nSkyDrive Albums\n";
foreach (AlbumInfo info in albumList.data)
{
string s = (info.Count == 1 ? String.Empty : "s");
this.outputText.Text += String.Format("{0} ({1} photo{2})\n", info.Name, info.Count, s);
}
}
/// <summary>
/// Build the API service URI.
/// </summary>
/// <param name="path">The relative path requested.</param>
/// <returns>The request URI.</returns>
private Uri BuildApiUri(string path)
{
UriBuilder builder = new UriBuilder(MainPage.ApiServiceUri);
builder.Path += path;
builder.Query = "access_token=" + HttpUtility.UrlEncode(this.accessToken);
return builder.Uri;
}
/// <summary>
/// Build the OAuth URI.
/// </summary>
/// <param name="scopes">The requested scopes.</param>
/// <returns>The OAuth URI.</returns>
private Uri BuildOAuthUri(string[] scopes)
{
List<string> paramList = new List<string>();
paramList.Add("client_id=" + HttpUtility.UrlEncode(MainPage.ClientId));
paramList.Add("scope=" + HttpUtility.UrlEncode(String.Join(" ", scopes)));
paramList.Add("response_type=" + HttpUtility.UrlEncode("token"));
paramList.Add("display=" + HttpUtility.UrlEncode("touch"));
paramList.Add("redirect_uri=" + HttpUtility.UrlEncode(MainPage.RedirectUri));
UriBuilder authorizeUri = new UriBuilder(MainPage.OAuthAuthorizeUri);
authorizeUri.Query = String.Join("&", paramList.ToArray());
return authorizeUri.Uri;
}
/// <summary>
/// Process the URI fragment string.
/// </summary>
/// <param name="fragment">The URI fragment.</param>
/// <returns>The key-value pairs.</returns>
private Dictionary<string, string> ProcessFragments(string fragment)
{
Dictionary<string, string> processedFragments = new Dictionary<string, string>();
if (fragment[0] == '#')
{
fragment = fragment.Substring(1);
}
string[] fragmentParams = fragment.Split('&');
foreach (string fragmentParam in fragmentParams)
{
string[] keyValue = fragmentParam.Split('=');
if (keyValue.Length == 2)
{
processedFragments.Add(keyValue[0], HttpUtility.UrlDecode(keyValue[1]));
}
}
return processedFragments;
}
/// <summary>
/// Handles the click event of the sign in button.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnSignInButtonClicked(object sender, RoutedEventArgs e)
{
this.LaunchOAuthFlow();
}
/// <summary>
/// Handles the navigating event of the OAuth web browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnAuthorizationBrowserNavigated(object sender, NavigationEventArgs e)
{
this.authorizationBrowser.Navigated -= this.OnAuthorizationBrowserNavigated;
this.loadingGrid.Visibility = Visibility.Collapsed;
this.authorizationBrowser.Visibility = Visibility.Visible;
}
/// <summary>
/// Handles the navigating event of the OAuth web browser control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnAuthorizationBrowserNavigating(object sender, NavigatingEventArgs e)
{
Uri uri = e.Uri;
if (uri != null && uri.AbsoluteUri.StartsWith(MainPage.RedirectUri))
{
Dictionary<string, string> fragments = this.ProcessFragments(uri.Fragment);
bool success = fragments.TryGetValue("access_token", out this.accessToken);
e.Cancel = true;
this.CompleteOAuthFlow(success);
}
}
/// <summary>
/// Handles the open read complete event of the <see cref="WebClient"/> object.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The event data.</param>
private void OnClientOpenReadComplete(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer deserializer;
if (e.UserState.Equals(Results.UserInfo))
{
deserializer = new DataContractJsonSerializer(typeof(UserInfo));
UserInfo userInfo = (UserInfo)deserializer.ReadObject(e.Result);
this.GetUserDataComplete(userInfo);
WebClient client = new WebClient();
client.OpenReadCompleted += this.OnClientOpenReadComplete;
client.OpenReadAsync(this.BuildApiUri(this.albums), Results.AlbumInfo);
}
else if (e.UserState.Equals(Results.AlbumInfo))
{
deserializer = new DataContractJsonSerializer(typeof(Albums));
Albums albumInfo = (Albums)deserializer.ReadObject(e.Result);
this.GetAlbumDataComplete(albumInfo);
}
}
}
}
AlbumInfo.cs 3.02KB
//-----------------------------------------------------------------------
// <copyright file="AlbumInfo.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace SkyDrive_Photos_Sample
{
/// <summary>
/// Represents the user that created the album
/// </summary>
[DataContract]
public class From
{
/// <summary>
/// Gets or sets the name of the user
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the id of the user
/// </summary>
[DataMember(Name = "id")]
public string Id
{
get;
set;
}
}
/// <summary>
/// Represents multiple albums returned in a JSON request
/// </summary>
public class Albums
{
public List<AlbumInfo> data { get; set; }
}
/// <summary>
/// Represents a photo album in SkyDrive.
/// </summary>
[DataContract]
public class AlbumInfo
{
/// <summary>
/// Gets or sets the id of the album
/// </summary>
[DataMember(Name = "id")]
public string Id
{
get;
set;
}
/// <summary>
/// Gets or sets the user who created the album
/// </summary>
[DataMember(Name = "from")]
public From From
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the album
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the description of the album
/// </summary>
[DataMember(Name = "description")]
public string Description
{
get;
set;
}
/// <summary>
/// Gets or sets the number of photos in the album
/// </summary>
[DataMember(Name = "count")]
public int Count
{
get;
set;
}
/// <summary>
/// Gets or sets the link to the album
/// </summary>
[DataMember(Name = "link")]
public string Link
{
get;
set;
}
/// <summary>
/// Gets or sets the type of folder in SkyDrive
/// </summary>
[DataMember(Name = "type")]
public string Type
{
get;
set;
}
/// <summary>
/// Gets or sets the created time of the album
/// </summary>
[DataMember(Name = "created_time")]
public string CreatedTime
{
get;
set;
}
/// <summary>
/// Gets or sets the updated time of the album
/// </summary>
[DataMember(Name = "updated_time")]
public string UpdatedTime
{
get;
set;
}
}
}
UserInfo.cs 1.42KB
//-----------------------------------------------------------------------
// <copyright file="UserInfo.cs" company="Microsoft Corp.">
// Copyright Microsoft Corp. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace SkyDrive_Photos_Sample
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Represents the user info returned by the "me" call.
/// </summary>
[DataContract]
public class UserInfo
{
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "name")]
public string Name
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "first_name")]
public string FirstName
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "last_name")]
public string LastName
{
get;
set;
}
/// <summary>
/// Gets or sets the name of the user.
/// </summary>
[DataMember(Name = "link")]
public string Link
{
get;
set;
}
}
}