Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Developing SevenDrops - A Dropbox-based photo uploader for Windows Phone 7 [2/6]

DZone's Guide to

Developing SevenDrops - A Dropbox-based photo uploader for Windows Phone 7 [2/6]

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

So now that there is a basic UI layout (described here) I can start working on the application functionality and the first thing I am going to start with is user authentication. Dropbox works in such a way that the user only has to log in once and receive a token that will later on associate him with the application (if you already know what I am talking about - that's OAuth). The received token is valid for ten years, therefore you won't have to perform the log in process anytime soon.

In this article I am going to focus particularly on the token, so you can follow through. When you sign up for a Dropbox application (can be done here), you get a unique key and secret.

 

Right now, the secret is not needed and only the key will be used. This key is passed as an oauth_consumer_key parameter to the authentication URL. The URL is stated in the API documentation:

https://api.dropbox.com/<version>/token

Version is currently set to 0, but as the service develops, this indicator might change. The consumer parameters are passed to the URL in this format:

https://api.dropbox.com/<version>/token?email=USER_EMAIL&
password=USER_PASSWORD&oath_consumer_key=APP_KEY

Notice that the user credentials are also passed to the URL, but you have to consider this recommendation from the Dropbox API docs (regarding the token method):

DO NOT STORE THE USER'S PASSWORD! The way this call works is you call it once with the user's email and password and then keep the token around for later. You do NOT (I repeat NOT) call this before everything you do or on each program startup. We watch for this and will shut down your application with little notice if we catch you. In fact, the Objective-C code does this for you so you can't get it wrong.

In my case I will not be storing the password - what I have is a custom page that will obtain the user credentials:

<phone:PhoneApplicationPage 
x:Class="SevenDrops.Credentials"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">

<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="credentials" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Email:" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="12,123,12,457"></TextBlock>
<TextBox x:Name="EmailField" Margin="0,170,0,387"></TextBox>
<TextBlock Margin="12,248,12,332" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="Password:" />
<PasswordBox x:Name="PasswordField" Margin="0,295,0,262" />
<Button x:Name="LogInButton" Content="Log In" Height="72" Margin="0,378,245,0" VerticalAlignment="Top" />
<Button x:Name="CancelButton" Content="Cancel" Height="72" Margin="245,378,0,0" VerticalAlignment="Top" />
</Grid>
</Grid>
</phone:PhoneApplicationPage>

It's really basic, but it's all that's needed.

Now when the user clicks on the Log In button, I need to check whether there are any empty fields (well, out of two of course). So there is the simple verification:

if ((!string.IsNullOrEmpty(EmailField.Text.Trim())) && (!string.IsNullOrEmpty(PasswordField.Password)))
{

}
else
{
MessageBox.Show("Both email and password are required.");
}

At this point this code won't do anything but bring up a warning if any of the user credentials are missing. Let's create a HTTP web request that will get the final token. Here is the modified version of the event handler tied to the Log In button:

private void LogInButton_Click(object sender, RoutedEventArgs e)
{
if ((!string.IsNullOrEmpty(EmailField.Text.Trim())) && (!string.IsNullOrEmpty(PasswordField.Password)))
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("https://api.dropbox.com/0/token?email=" + EmailField.Text + "&password=" +
PasswordField.Password + "&oauth_consumer_key=" + KEY);
var n = Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse,request.EndGetResponse)();
n.Subscribe(HandleResult);
}
else
{
MessageBox.Show("Both email and password are required.");
}
}

KEY here is a string constant that represents the application key provided by Dropbox and it is private, so I cannot share it here. As you can also see, I am using Reactive Extensions here - the HTTP request retrieval and handling are wrapped in Observable.FromAsyncPattern.

You have to add the following using statement in the class header:

using Microsoft.Phone.Reactive;

Of course you would have to add a library reference first. Also, don't forget about System.Observable.dll.

Now I actually need to get the token from the response, and to do this there is the HandleResult method, referenced above when subscribing to the observer:

private void HandleResult(WebResponse response)
{
HttpWebResponse _response = (HttpWebResponse)response;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string a = reader.ReadToEnd();
Debug.WriteLine(a);
}
}

Now if you launch the application, given that you already have a Dropbox account, when you authorize it (by the way you can simply use NavigationService.Navigate(new Uri("/Credentials.xaml", UriKind.Relative)); to get to the log in page) you should see the new token and secret displayed in the output window:

No, you won't see mine. But as you can see, this is JSON-formatted data. In the next article I will be diving deeper in OAuth and will show you how the JSON elements will be deserialized to raw data that can be used by the application.

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}