<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Christophe Geers&#039; Blog</title>
	<atom:link href="http://cgeers.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cgeers.com</link>
	<description>Christophe Geers&#039; Blog about .NET programming</description>
	<lastBuildDate>Mon, 21 May 2012 20:29:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='cgeers.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Christophe Geers&#039; Blog</title>
		<link>http://cgeers.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://cgeers.com/osd.xml" title="Christophe Geers&#039; Blog" />
	<atom:link rel='hub' href='http://cgeers.com/?pushpress=hub'/>
		<item>
		<title>SkyDrive: Listing Folders and Files</title>
		<link>http://cgeers.com/2012/05/01/skydrive-listing-folders-and-files/</link>
		<comments>http://cgeers.com/2012/05/01/skydrive-listing-folders-and-files/#comments</comments>
		<pubDate>Tue, 01 May 2012 17:56:41 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Live SDK]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SkyDrive]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=4198</guid>
		<description><![CDATA[Introduction The previous article, Getting Started with the Live SDK: Authorization, shows you have to request a user&#8217;s permission to access parts of their Live ID, including SkyDrive. Time to take a closer look at what we can do with the REST API and SkyDrive. Listing a user&#8217;s folders and files stored in his SkyDrive [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4198&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2012/04/live.png"><img src="http://cgeers.files.wordpress.com/2012/04/live.png?w=480" alt="Live SDK" title="Live SDK"   class="alignright size-full wp-image-4149" /></a></p>
<p>The previous article, <a href="http://cgeers.com/2012/04/29/getting-started-with-the-live-sdk-authorization/" target="_blank">Getting Started with the Live SDK: Authorization</a>, shows you have to request a user&#8217;s permission to access parts of their Live ID, including SkyDrive.</p>
<p>Time to take a closer look at what we can do with the REST API and SkyDrive. Listing a user&#8217;s folders and files stored in his SkyDrive seems like as good as any place to start.</p>
<p><span id="more-4198"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#scopes">Scopes</a></li>
<li><a href="#folders">Folders, Albums, Files, Photos, Videos&#8230;</a></li>
<li><a href="#listing">Listing Folders</a></li>
<li><a href="#othercontent">Other Content Types</a></li>
<li><a href="#foldercontents">Folder Contents</a></li>
</ul>
<p><a title="scopes" name="scopes"></a><strong>Scopes</strong></p>
<p>When the user authorizes your application you can specify the scopes to which you want access. Their profile, work information, postal addresses&#8230;etc. The list goes on, you can find it here:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/live/hh243646" target="_blank">http://msdn.microsoft.com/en-us/library/live/hh243646</a></p>
<p>If you want to list the folders and files of the user&#8217;s SkyDrive account you need to make sure you request access for the following scopes:</p>
<ul>
<li><strong>wl.skydrive</strong>: Read access to a user&#8217;s files stored in SkyDrive.</li>
<li><strong>wl.photos</strong>: Read access to a user&#8217;s photos, videos, audio, and albums.</li>
</ul>
<p>So let&#8217;s quickly generate a new access token:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> uri = <span class="str">"https://login.live.com/oauth20_authorize.srf"</span>;

<span class="kwrd">var</span> authorizeUri = <span class="kwrd">new</span> StringBuilder(uri);

authorizeUri.AppendFormat(<span class="str">"?client_id={0}&amp;"</span>, <span class="str">"your_client_id"</span>);
authorizeUri.AppendFormat(<span class="str">"scope={0}&amp;"</span>, 
    <span class="str">"wl.signin%20wl.photos%20wl.skydrive"</span>);
authorizeUri.AppendFormat(<span class="str">"response_type={0}&amp;"</span>, <span class="str">"token"</span>);
authorizeUri.AppendFormat(<span class="str">"redirect_uri={0}"</span>, 
UrlEncode(<span class="str">"http://redirect_uri.com"</span>));</pre>
</div>
<p><strong>Remark</strong>: Each scope value needs to be separated by a space (%20). For brevity&#8217;s sake I&#8217;ve put them in there directly.</p>
<p>The user will asked to grant the necessary permissions:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/05/skydrive1.png"><img src="http://cgeers.files.wordpress.com/2012/05/skydrive1.png?w=480" alt="SkyDrive Scopes" title="SkyDrive Scopes"   class="aligncenter size-full wp-image-4208" /></a></p>
<p>Permissions to which you already have access will not be listed again. Need more information on authorizing your application? Check ouf the <a href="http://cgeers.com/2012/04/29/getting-started-with-the-live-sdk-authorization/" target="_blank">first article</a>.</p>
<p>When the user authorizes your application you will be redirected to the URL you specified and it will contain an authorization token. Get it. Even if it is ridiculously long.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="folders" name="folders"></a><strong>Folders, Albums, Files, Photos, Videos&#8230;</strong></p>
<p>If you take a look at the <a href="http://msdn.microsoft.com/en-us/library/live/hh243648.aspx" target="_blank">REST reference</a> you&#8217;ll find a couple of objects connected to SkyDrive such as Folder, Album, File, Photo, Video&#8230;etc. Most of them share a lot of properties, so let&#8217;s create a base class for them.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[JsonObject(MemberSerialization.OptIn)]
<span class="kwrd">public</span> <span class="kwrd">class</span> FileSystemInfo
{
    [JsonProperty(PropertyName = <span class="str">"id"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Id { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"name"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Name { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"created_time"</span>)]
    [JsonConverter(<span class="kwrd">typeof</span>(IsoDateTimeConverter))]
    <span class="kwrd">public</span> DateTime CreatedTime { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"type"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Type { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    <span class="rem">//...</span>
}</pre>
</div>
<p>I&#8217;ve not listed all the properties here, there are too many. Check out the REST reference, compare the objects and add the common properties. The JSON.NET attributes will help us later when deserialing the response.</p>
<p>Photos have a couple of different properties. Let&#8217;s add those to a descendant class.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[JsonObject(MemberSerialization.OptIn)]
<span class="kwrd">public</span> <span class="kwrd">class</span> Photo : FileSystemInfo
{
    [JsonProperty(<span class="str">"size"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">int</span> Size { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(<span class="str">"when_taken"</span>)]
    <span class="kwrd">public</span> DateTime? WhenTaken { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(<span class="str">"location"</span>)]
    <span class="kwrd">public</span> Location Location { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    <span class="rem">//...</span>
}</pre>
</div>
<p>Again not all properties are listed. Check out the <a href="http://msdn.microsoft.com/en-us/library/live/hh243648.aspx#photo" target="_blank">Photo Object</a> if you want to add more.</p>
<p>The same goes for the Video object. I&#8217;ll not list it here, just check out the source code that comes with this article. </p>
<p>Did you notice the Type (string) property on the FileSystemInfo class? This type will tell us what type of object we are dealing with. Folder, photo, video&#8230;etc. It will come in handy when deserializing the returned data.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="listing" name="listing"></a><strong>Listing Folders</strong></p>
<p>To list all the folder of a user&#8217;s SkyDrive account you simply sent a GET request to:</p>
<p><a href="https://apis.live.net/v5.0/me/skydrive/files" target="_blank">https://apis.live.net/v5.0/me/skydrive/files</a></p>
<p>Just don&#8217;t forget to append the access token.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> requestUri = <span class="kwrd">new</span> StringBuilder(<span class="str">"https://apis.live.net/v5.0/me/skydrive/files"</span>);
requestUri.AppendFormat(<span class="str">"?access_token={0}"</span>, <span class="str">"access token"</span>);
<span class="kwrd">var</span> request = (HttpWebRequest)WebRequest.Create(requestUri.ToString());
request.Method = <span class="str">"GET"</span>;</pre>
</div>
<p>The response will, as always, be JSON-formatted. Let&#8217;s deserialize it to an IEnumerable of Folder. But first add the following SkyDrive type to your project.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[JsonObject(MemberSerialization.OptIn)]
<span class="kwrd">public</span> <span class="kwrd">class</span> SkyDrive
{
    [JsonProperty(PropertyName = <span class="str">"data"</span>)]
    <span class="kwrd">public</span> IEnumerable&lt;Folder&gt; Folders { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }
}</pre>
</div>
<p>Now you can easily deserialize the list of folders.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> response = (HttpWebResponse)request.GetResponse();
<span class="kwrd">using</span> (<span class="kwrd">var</span> reader = <span class="kwrd">new</span> StreamReader(response.GetResponseStream()))
{
    <span class="kwrd">var</span> json = reader.ReadToEnd();

    <span class="kwrd">var</span> skyDrive = JsonConvert.DeserializeObject&lt;SkyDrive&gt;(json);

    <span class="kwrd">foreach</span> (<span class="kwrd">var</span> folder <span class="kwrd">in</span> skyDrive.Folders)
    {
        Console.WriteLine(String.Format(<span class="str">"{0}: {1}"</span>, folder.Id, folder.Name));
    }
}</pre>
</div>
<p>This will output all the folders in the user&#8217;s SkyDrive root.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/05/skydrive2.png"><img src="http://cgeers.files.wordpress.com/2012/05/skydrive2.png?w=480&h=123" alt="SkyDrive Folders" title="SkyDrive Folders" width="480" height="123" class="aligncenter size-full wp-image-4219" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="othercontent" name="othercontent"></a><strong>Other Content Types</strong></p>
<p>The previous example is a bit hopeful. Only store folders and you&#8217;ll be fine. No files please. They will be treated as folders.</p>
<p>To use the other content types (album, photo, video, file&#8230;etc.) you have to inspect the type property. Once you have the JSON response, parse it and inspect the returned data.</p>
<p>For example:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> json = JObject.Parse(reader.ReadToEnd());

<span class="kwrd">var</span> contents = <span class="kwrd">new</span> List&lt;FileSystemInfo&gt;();
<span class="kwrd">foreach</span> (<span class="kwrd">var</span> item <span class="kwrd">in</span> json[<span class="str">"data"</span>])
{
    <span class="kwrd">var</span> type = item[<span class="str">"type"</span>].ToString();
    <span class="kwrd">switch</span> (type)
    {
        <span class="kwrd">case</span> <span class="str">"photo"</span>:
            contents.Add(JsonConvert.DeserializeObject&lt;Photo&gt;(item.ToString()));
            <span class="kwrd">break</span>;

        <span class="kwrd">case</span> <span class="str">"video"</span>:
            contents.Add(JsonConvert.DeserializeObject&lt;Video&gt;(item.ToString()));
            <span class="kwrd">break</span>;

        <span class="kwrd">case</span> <span class="str">"folder"</span>:
        <span class="kwrd">case</span> <span class="str">"album"</span>:
            contents.Add(JsonConvert.DeserializeObject&lt;Folder&gt;(item.ToString()));
            <span class="kwrd">break</span>;
    }
}</pre>
</div>
<p>Then you can list all the content types and use their specific properties.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">foreach</span> (<span class="kwrd">var</span> item <span class="kwrd">in</span> contents)
{
    Console.WriteLine(String.Format(<span class="str">"{0} : {1}"</span>, item.Type, item.Name));
    <span class="kwrd">if</span> (item <span class="kwrd">is</span> Photo)
    {
        Console.WriteLine(String.Format(<span class="str">"Size: {0} bytes"</span>, ((Photo) item).Size));
    }
}</pre>
</div>
<p><a href="#top">Top of page</a></p>
<p><a title="foldercontents" name="foldercontents"></a><strong>Folder Contents</strong></p>
<p>One last thing I want to address for this post is how to list a folder&#8217;s contents. Listing the folders of the root folder will not return the contents (files, subfolders&#8230;) of these folders.</p>
<p>However requesting the contents of a folder is very similar. Instead of sending a GET request to:</p>
<p><a href="https://apis.live.net/v5.0/me/skydrive/files" target="_blank">https://apis.live.net/v5.0/me/skydrive/files</a></p>
<p>You need to send a request to:</p>
<p><a href="https://apis.live.net/v5.0/{folder_id}/files" target="_blank">https://apis.live.net/v5.0/{folder_id}/files</a></p>
<p>Just replace {folder_id} with the ID of the folder for which you want to list the contents and you are set.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> uri = <span class="str">"https://apis.live.net/v5.0/{0}/files"</span>;
<span class="kwrd">var</span> requestUri = <span class="kwrd">new</span> StringBuilder(String.Format(uri, <span class="str">"your_folder_id"</span>));
requestUri.AppendFormat(<span class="str">"?access_token={0}"</span>, <span class="str">"your_access_token"</span>);
<span class="kwrd">var</span> request = (HttpWebRequest)WebRequest.Create(requestUri.ToString());
request.Method = <span class="str">"GET"</span>;

<span class="kwrd">var</span> response = (HttpWebResponse)request.GetResponse();
<span class="kwrd">using</span> (<span class="kwrd">var</span> reader = <span class="kwrd">new</span> StreamReader(response.GetResponseStream()))
{
    <span class="kwrd">var</span> json = JObject.Parse(reader.ReadToEnd());

    <span class="rem">// Parse the JSON data here</span>
    <span class="rem">// ...</span>
}</pre>
</div>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/live-sdk/'>Live SDK</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/4198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/4198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/4198/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4198&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/05/01/skydrive-listing-folders-and-files/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live.png" medium="image">
			<media:title type="html">Live SDK</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/05/skydrive1.png" medium="image">
			<media:title type="html">SkyDrive Scopes</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/05/skydrive2.png" medium="image">
			<media:title type="html">SkyDrive Folders</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Started with the Live SDK: Authorization</title>
		<link>http://cgeers.com/2012/04/29/getting-started-with-the-live-sdk-authorization/</link>
		<comments>http://cgeers.com/2012/04/29/getting-started-with-the-live-sdk-authorization/#comments</comments>
		<pubDate>Sun, 29 Apr 2012 09:00:08 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Live SDK]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Hotmail]]></category>
		<category><![CDATA[Messenger]]></category>
		<category><![CDATA[SkyDrive]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=4147</guid>
		<description><![CDATA[Introduction In a move to compete with DropBox, Google Drive&#8230;etc. Microsoft revamped SkyDrive this week incorporating most of Mesh&#8216;s features. If you signed up for SkyDrive before April 22nd, and have uploaded at least one file, be sure to apply for the free upgrade to 25 GB. I wrote a couple of articles on the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4147&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2012/04/live.png"><img src="http://cgeers.files.wordpress.com/2012/04/live.png?w=480" alt="Live SDK" title="Live SDK"   class="alignright size-full wp-image-4149" /></a></p>
<p>In a move to compete with DropBox, Google Drive&#8230;etc. Microsoft revamped SkyDrive this week incorporating most of <a href="http://windows.microsoft.com/en-US/windows-live/mesh-devices-sync-upgrade-ui" target="_blank">Mesh</a>&#8216;s features. If you signed up for SkyDrive before April 22nd, and have uploaded at least one file, be sure to apply for the <a href="https://skydrive.live.com/ManageStorage" target="_blank">free upgrade</a> to 25 GB.</p>
<p>I wrote a couple of articles on the use of the <a href="http://cgeers.com/category/programming/dropbox/" target="_blank">DropBox REST API</a>. Microsoft&#8217;s revamp made me curious to see if I could do the same with the SkyDrive API.</p>
<p><span id="more-4147"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#registration">Register Your Application</a></li>
<li><a href="#rest">REST Reference</a></li>
<li><a href="#oauth">OAuth</a></li>
<li><a href="#user">User Object</a></li>
</ul>
<p><a title="registration" name="registration"></a><strong>Register Your Application</strong></p>
<p>The SkyDrive API is part of the Live SDK, which allows you to use SkyDrive, Hotmail, Messenger and Live Id. Before you can get started you need to register your application at the <a href="http://msdn.microsoft.com/en-us/live/ff519582" target="_blank">Live Connect Developer Center</a>.</p>
<p>Just sign in with your Windows Live Id and then click &#8220;My Apps&#8221; in the upper left corner.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live2.png"><img src="http://cgeers.files.wordpress.com/2012/04/live2.png?w=480&h=86" alt="Live SDK - My Apps" title="Live SDK - My Apps" width="480" height="86" class="aligncenter size-full wp-image-4156" /></a></p>
<p>You have 100 available application slots. Just click &#8220;Create Application&#8221;. You only need to fill in two fields, the application&#8217;s name and language.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live3.png"><img src="http://cgeers.files.wordpress.com/2012/04/live3.png?w=480" alt="Create Application" title="Create Application"   class="aligncenter size-full wp-image-4158" /></a></p>
<p>Afterwards you&#8217;ll receive a client ID and secret.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live4.png"><img src="http://cgeers.files.wordpress.com/2012/04/live4.png?w=480" alt="Client ID and Secret" title="Client ID and Secret"   class="aligncenter size-full wp-image-4159" /></a></p>
<p>Yes, I changed the secret by the time you are reading this.</p>
<p>After you&#8217;ve created the application you need to change one little thing. Go back to the applications overview page and select the newly created application. Click &#8220;Edit Settings&#8221; and then select the &#8220;API Settings&#8221; option. Here you need to enter a valid redirect domain. This needs to be set correctly if you want the authorization process to succeed.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live5.png"><img src="http://cgeers.files.wordpress.com/2012/04/live5.png?w=480" alt="Redirect Domain" title="Redirect Domain"   class="aligncenter size-full wp-image-4161" /></a></p>
<p><strong>Remark</strong>: You can only use the same redirect domain for one application!</p>
<p><a href="#top">Top of page</a></p>
<p><a title="rest" name="rest"></a><strong>REST Reference</strong></p>
<p>You can use the Representation State Transfer (REST) API to work with the Live API. Using the REST API you can programmatically access the user&#8217;s info, contacts, friends, addresses&#8230;etc. </p>
<p>You can find the entire REST reference here:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/live/hh243648.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/live/hh243648.aspx</a></p>
<p>Alternatively you can also download the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=8615" target="_blank">Windows Live SDK</a>. The SDK simplifies common task such as signing in, access user data..etc, but I prefer to use the REST API directly.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="oauth" name="oauth"></a><strong>OAuth</strong></p>
<p>Live Connect implements the <a href="http://oauth.net/" target="_blank">OAuth</a> 2.0 protocol to authenticate users. I already covered OAuth in the following articles:</p>
<ul>
<li><a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/" target="_blank">Dropbox REST API Part 1: Authentication</a></li>
<li><a href="http://cgeers.com/2012/03/17/dropbox-rest-api-part-6-oauth-callback/" target="_blank">Dropbox REST API Part 6: OAuth Callback</a></li>
<li><a href="http://cgeers.com/2012/04/21/bitly-api-authentication/" target="_blank">Bitly API: Authentication</a></li>
</ul>
<p>The implementation is similar for the Live Connect API. Let&#8217;s quickly cover the authorization flow.</p>
<p>First you need to compose the authorization URL to which you&#8217;ll redirect the users.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> uri = <span class="str">"https://login.live.com/oauth20_authorize.srf"</span>;

<span class="kwrd">var</span> authorizeUri = <span class="kwrd">new</span> StringBuilder(uri);

authorizeUri.AppendFormat(<span class="str">"?client_id={0}&amp;"</span>, <span class="str">"Your Client ID"</span>);
authorizeUri.AppendFormat(<span class="str">"scope={0}&amp;"</span>, <span class="str">"wl.signin"</span>);
authorizeUri.AppendFormat(<span class="str">"response_type={0}&amp;"</span>, <span class="str">"token"</span>);
authorizeUri.AppendFormat(<span class="str">"redirect_uri={0}"</span>, UrlEncode(<span class="str">"http://redirect_url.com"</span>));</pre>
</div>
<p>Fill in your client ID and make sure that the redirect URL exactly matches the one you entered when you registered your application.</p>
<p>Using the scope query parameter you can specify the permissions which your application requires. If you want to sign in the user you specify <strong>wl.signin</strong>. If you also want to access the user&#8217;s work profile and postal addresses you need to also pass <strong>wl.work_profile</strong> and <strong>wl.postal_addresses</strong>. You can find a list of all the available scopes here:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/live/hh243646" target="_blank">http://msdn.microsoft.com/en-us/library/live/hh243646</a></p>
<p>Each scope value needs to be separated by a space (%20).</p>
<p>The value of the response_type query parameter is set to token which requests an authorization token.</p>
<p><strong>Remark</strong>: The UrlEncode(&#8230;) method encodes the redirect URI. Check out the source code of this article to see how the method works. I already explained it in <a href="http://cgeers.com/2012/03/11/dropbox-rest-api-part-5-file-upload/#urlencoding" target="_blank">Part 5</a> of the Dropbox series.</p>
<p>Once you&#8217;ve composed the authorization URI you can redirect the user to it.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> startInfo = <span class="kwrd">new</span> ProcessStartInfo();
startInfo.FileName = authorizeUri.ToString();
Process.Start(startInfo);</pre>
</div>
<p>The user will be informed to which parts of his account your application wants access.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live6.png"><img src="http://cgeers.files.wordpress.com/2012/04/live6.png?w=480" alt="Allow Access?" title="Allow Access?"   class="aligncenter size-full wp-image-4178" /></a></p>
<p>After the user authorizes your application he&#8217;ll be redirected to the URI you specified in the redirect_uri parameter. The redirect URI will be appended with 5 parameters, namely:</p>
<ul>
<li><strong>access_token</strong>: The access token</li>
<li><strong>authentication_token</strong></li>
<li><strong>token_type</strong></li>
<li><strong>expires_in</strong>: The number of seconds the access token is valid</li>
<li><strong>scope</strong>: The scopes to which the user granted you access</li>
</ul>
<p>Microsoft uses redictiously long token, over 700 characters! Seriously, why? I believe an Dropbox&#8217;s access token is about 12 characters long (may vary).</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live71.png"><img src="http://cgeers.files.wordpress.com/2012/04/live71.png?w=480" alt="Bitch Please" title="Bitch Please"   class="aligncenter size-full wp-image-4184" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="user" name="user"></a><strong>User Object</strong></p>
<p>Now that we have access to the user&#8217;s account let&#8217;s retrieve some profile information. The data is exchanged in JavaScript Object Notation (JSON) format. </p>
<p>For example:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
{
    "id": "2a67eedc508758ca", 
    "name": "Christophe Geers", 
    "first_name": "Christophe", 
    "last_name": "Geers", 
    "gender": null, 
    "locale": "nl_NL"
}</pre>
</div>
<p>So add a reference to the <a href="http://james.newtonking.com/" target="_blank">JSON.NET library</a> via NuGet. Now let&#8217;s create a simple <a href="http://msdn.microsoft.com/en-us/library/live/hh243648.aspx#user" target="_blank">User object</a> into which we can deserialize this data.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[JsonObject(MemberSerialization.OptIn)]
<span class="kwrd">public</span> <span class="kwrd">class</span> User
{
    [JsonProperty(PropertyName = <span class="str">"id"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Id { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"name"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Name { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"first_name"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> FirstName { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"last_name"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> LastName { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"gender"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Gender { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"locale"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Locale { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }
}</pre>
</div>
<p>When you request information about a user&#8217;s profile you need to send a GET request to:</p>
<p><a href="https://apis.live.net/v5.0/me" target="_blank">https://apis.live.net/v5.0/me</a></p>
<p>Instead of the term &#8220;me&#8221; you can also use the user&#8217;s ID, but this way is simpler as you don&#8217;t have to figure out the user&#8217;s ID first.</p>
<p>First you need to compose the request:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> requestUri = <span class="kwrd">new</span> StringBuilder(<span class="str">"https://apis.live.net/v5.0/me"</span>);
requestUri.AppendFormat(<span class="str">"?access_token={0}"</span>, <span class="str">"your access token"</span>);
<span class="kwrd">var</span> request = (HttpWebRequest)WebRequest.Create(requestUri.ToString());
request.Method = <span class="str">"GET"</span>;</pre>
</div>
<p>Then you can read the response. Using the JSON.NET library you can easily deserialize it into an instance of the User type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> response = (HttpWebResponse) request.GetResponse();
<span class="kwrd">using</span> (<span class="kwrd">var</span> reader = <span class="kwrd">new</span> StreamReader(response.GetResponseStream()))
{
    <span class="kwrd">var</span> json = reader.ReadToEnd();

    <span class="kwrd">var</span> user = JsonConvert.DeserializeObject&lt;User&gt;(json);

    Console.WriteLine(user.Id);
    Console.WriteLine(user.Name);
    Console.WriteLine(user.FirstName);
    Console.WriteLine(user.LastName);
    Console.WriteLine(user.Gender);
    Console.WriteLine(user.Locale);
}</pre>
</div>
<p>The output:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/live8.png"><img src="http://cgeers.files.wordpress.com/2012/04/live8.png?w=480&h=123" alt="User Object Output" title="User Object Output" width="480" height="123" class="aligncenter size-full wp-image-4193" /></a></p>
<p>If you want to retrieve more data from the user&#8217;s profile you need to specify the correct scopes (wl.work_profile, wl.postal_addresses&#8230;) when requesting access to the user&#8217;s account. Download the source of this article and check it out. There you can find some examples about how to retrieve the user&#8217;s work profile and postal addresses.</p>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/live-sdk/'>Live SDK</a>, <a href='http://cgeers.com/category/programming/oauth/'>OAuth</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/4147/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/4147/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/4147/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4147&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/04/29/getting-started-with-the-live-sdk-authorization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live.png" medium="image">
			<media:title type="html">Live SDK</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live2.png" medium="image">
			<media:title type="html">Live SDK - My Apps</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live3.png" medium="image">
			<media:title type="html">Create Application</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live4.png" medium="image">
			<media:title type="html">Client ID and Secret</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live5.png" medium="image">
			<media:title type="html">Redirect Domain</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live6.png" medium="image">
			<media:title type="html">Allow Access?</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live71.png" medium="image">
			<media:title type="html">Bitch Please</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/live8.png" medium="image">
			<media:title type="html">User Object Output</media:title>
		</media:content>
	</item>
		<item>
		<title>Bitly API: Authentication</title>
		<link>http://cgeers.com/2012/04/21/bitly-api-authentication/</link>
		<comments>http://cgeers.com/2012/04/21/bitly-api-authentication/#comments</comments>
		<pubDate>Sat, 21 Apr 2012 12:01:50 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bitly]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=4107</guid>
		<description><![CDATA[Introduction I was playing around this morning with the Bitly API. Like the Dropbox API they use OAuth for authentication. But instead of version 1.0 they use the OAuth 2 draft specification. Wondering how much it differs from the previous version I created a Bitly account and started coding&#8230; Table Of Contents Introduction Register Your [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4107&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://www.bitly.com"><img src="http://cgeers.files.wordpress.com/2012/04/bitly1.png?w=480" alt="" title="Bitly"   class="alignright size-full wp-image-4111" /></a></p>
<p>I was playing around this morning with the <a href="http://dev.bitly.com/api.html" target="_blank">Bitly API</a>. Like the <a href="http://cgeers.com/category/programming/dropbox/" target="_blank">Dropbox API</a> they use <a href="http://oauth.net/" target="_blank">OAuth</a> for authentication. But instead of version 1.0 they use the OAuth 2 draft specification.</p>
<p>Wondering how much it differs from the previous version I created a Bitly account and started coding&#8230;</p>
<p><span id="more-4107"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#registration">Register Your Application</a></li>
<li><a href="#authorization">Authorization</a></li>
<li><a href="#accesstoken">Access Token</a></li>
</ul>
<p><a title="registration" name="registration"></a><strong>Register Your Application</strong></p>
<p>If you don&#8217;t have a Bitly account yet, then sign up here:</p>
<p><a href="http://bitly.com/a/sign_up" target="_blank">http://bitly.com/a/sign_up</a></p>
<p>It&#8217;s quick and painless, I promise.</p>
<p>Once signed up, you need to register your application. Just select your account&#8217;s settings.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/bitly21.png"><img src="http://cgeers.files.wordpress.com/2012/04/bitly21.png?w=480" alt="Bitly Account Settings" title="Bitly Account Settings"   class="aligncenter size-full wp-image-4117" /></a></p>
<p>At the bottom you&#8217;ll find a list of your registered OAuth applications. You are allowed to create 3 applications under a single Bitly account. Just click the Register OAuth Application button to register a new application.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/bitly3.png"><img src="http://cgeers.files.wordpress.com/2012/04/bitly3.png?w=480" alt="Register OAuth Application" title="Register OAuth Application"   class="aligncenter size-full wp-image-4118" /></a></p>
<p>First you need to request a registration code. This code will be sent to the e-mail address associated with your Bitly account. Go ahead and click the &#8220;Get Registration Code&#8221; button.</p>
<p>Once you have received the e-mail, click on the registration code within it. You&#8217;ll be redirected to a form where you need to fill in the application&#8217;s name, link and description. </p>
<p>For example:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/bitly4.png"><img src="http://cgeers.files.wordpress.com/2012/04/bitly4.png?w=480&h=519" alt="Create Bitly Application" title="Create Bitly Application" width="480" height="519" class="aligncenter size-full wp-image-4120" /></a></p>
<p>After you&#8217;ve filled in the form and submitted it, your new application will be listed on your account. Per application you&#8217;ll receive an application link, client id and client secret. You&#8217;ll need these during the OAuth authentication process.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/bitly51.png"><img src="http://cgeers.files.wordpress.com/2012/04/bitly51.png?w=480&h=111" alt="Registered Applications" title="Registered Applications" width="480" height="111" class="aligncenter size-full wp-image-4127" /></a></p>
<p>There seems no way to edit or remove a registered application afterwards. A pity.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="authorization" name="authorization"></a><strong>Authorization</strong></p>
<p>Alright, Bitly account created, registered the application. Time to start the authentication process.</p>
<p>First you need to redirect the user to <a href="https://bitly.com/oauth/authorize" target="_blank">https://bitly.com/oauth/authorize</a>. You need to append your client id and application link (a.k.a. redirect uri) in the query string.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> redirectUri = <span class="str">"http://cgeers.com/"</span>;
<span class="kwrd">var</span> uri = <span class="str">"https://bitly.com/oauth/authorize"</span>;

<span class="kwrd">var</span> authorizeUri = <span class="kwrd">new</span> StringBuilder(uri);
authorizeUri.AppendFormat(<span class="str">"?client_id={0}&amp;"</span>, clientId);
authorizeUri.AppendFormat(<span class="str">"redirect_uri={0}"</span>, redirectUri);</pre>
</div>
<p>You&#8217;ll wind up with a URL that looks like this:</p>
<p><a href="https://bitly.com/oauth/authorize?client_id=your_client_id&amp;redirect_uri=your_application_link" target="_blank">https://bitly.com/oauth/authorize?client_id=your_client_id&amp;redirect_uri=your_application_link</a></p>
<p><strong>Remark</strong>: Make sure that the value of the redirect_uri parameter exactly matches the URL to which you linked your application! If you forget the last forward slash it will not work.</p>
<p>Now you need to redirect your user to this URL so that he or she can authorize your application.</p>
<p>A crude example:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> startInfo = <span class="kwrd">new</span> ProcessStartInfo();
startInfo.FileName = authorizeUri.ToString();
Process.Start(startInfo);</pre>
</div>
<p>The user will be redirect to a page where he can grant your applicion access to his Bitly account.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/bitly6.png"><img src="http://cgeers.files.wordpress.com/2012/04/bitly6.png?w=480&h=122" alt="Grant Access" title="Grant Access" width="480" height="122" class="aligncenter size-full wp-image-4132" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="accesstoken" name="accesstoken"></a><strong>Access Token</strong></p>
<p>When the user authorizes your application, he will be redirected to the URL specified by the redirect_uri parameter. Bitly appends a code to this URI. You can exchange this code for an OAuth access token.</p>
<p>For example:</p>
<p><a href="http://cgeers.com/?code=ddc08e777c8e4d911fb24ab9c2cc19b640265bfe" target="_blank">http://cgeers.com/?code=ddc08e777c8e4d911fb24ab9c2cc19b640265bfe</a></p>
<p>You need to retrieve the OAuth token using the <a href="https://api-ssl.bitly.com/oauth/access_token" target="_blank">https://api-ssl.bitly.com/oauth/access_token</a> endpoint.</p>
<p>You&#8217;ll need to append four parameters to it, namely:</p>
<ul>
<li><strong>client_id</strong>: your application&#8217;s Bitly client id</li>
<li><strong>client_secret</strong>: your application&#8217;s Bitly client secret</li>
<li><strong>code</strong>: the code acquired via the authorization step</li>
<li><strong>redirect_uri</strong>: the page to which a user was redirected upon successfully authenticating</li>
</ul>
<p>Let&#8217;s compose this URL:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> redirectUri = <span class="str">"http://cgeers.com/"</span>;
<span class="kwrd">var</span> code = <span class="str">"6c9f6ec95f54ba7269d0ba037b3eba7137559556"</span>;

<span class="kwrd">var</span> requestUri = <span class="kwrd">new</span> StringBuilder(<span class="str">"https://api-ssl.bitly.com/oauth/access_token"</span>);
requestUri.AppendFormat(<span class="str">"?client_id={0}&amp;"</span>, clientId);
requestUri.AppendFormat(<span class="str">"client_secret={0}&amp;"</span>, clientSecret);
requestUri.AppendFormat(<span class="str">"code={0}&amp;"</span>, code);
requestUri.AppendFormat(<span class="str">"redirect_uri={0}"</span>, redirectUri);</pre>
</div>
<p>You&#8217;ll end up with something like this:</p>
<p><a href="https://api-ssl.bitly.com/oauth/access_token?client_id=your_client_id&amp;client_secret=your_client_secret&amp;code=your_code&amp;redirect_uri=your_app_uri" target="_blank">https://api-ssl.bitly.com/oauth/access_token?client_id=your_client_id&amp;client_secret=your_client_secret&amp;code=your_code&amp;redirect_uri=your_app_uri</a></p>
<p>Once again make sure that the values for all the parameters match exactly.</p>
<p>Now you&#8217;ll need to issue a POST request (required), a GET request will not work, to obtain the response.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> request = (HttpWebRequest) WebRequest.Create(requestUri.ToString());
request.Method = WebRequestMethods.Http.Post;

<span class="kwrd">var</span> response = request.GetResponse();
<span class="kwrd">using</span> (<span class="kwrd">var</span> reader = <span class="kwrd">new</span> StreamReader(response.GetResponseStream()))
{
    <span class="kwrd">var</span> accessToken = reader.ReadToEnd();
    <span class="rem">//...</span>
}</pre>
</div>
<p>The response is a simple query string which will look something like this:</p>
<p>access_token=your_access_token&amp;login=user_login&amp;apiKey=users_api_key</p>
<p>Just split the string and extract the different parts.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> parts = accessToken.Split(<span class="str">'&amp;'</span>);
<span class="kwrd">var</span> token = parts[0].Substring(parts[0].IndexOf(<span class="str">'='</span>) + 1);
<span class="kwrd">var</span> login = parts[1].Substring(parts[1].IndexOf(<span class="str">'='</span>) + 1);
<span class="kwrd">var</span> apiKey = parts[2].Substring(parts[2].IndexOf(<span class="str">'='</span>) + 1);</pre>
</div>
<p>You now have an access token for the user. Make sure you persist it somewhere. You don&#8217;t want to put the user through the authentication process again. </p>
<p>Once you&#8217;ve issued this request the code becomes useless. If you perform the request again using the same code you&#8217;ll receive a 401 Http status code (unauthorized).</p>
<p>All Bitly API requests must be made over SSL (<a href="https://api-sll.bitly.com/" target="_blank">https://api-sll.bitly.com/</a>). You can use the access token on behalf of the user. Perhaps I&#8217;ll write another blog post that shows how to perform API requests. Stay tuned.</p>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/oauth/'>OAuth</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/4107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/4107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/4107/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4107&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/04/21/bitly-api-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly1.png" medium="image">
			<media:title type="html">Bitly</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly21.png" medium="image">
			<media:title type="html">Bitly Account Settings</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly3.png" medium="image">
			<media:title type="html">Register OAuth Application</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly4.png" medium="image">
			<media:title type="html">Create Bitly Application</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly51.png" medium="image">
			<media:title type="html">Registered Applications</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/bitly6.png" medium="image">
			<media:title type="html">Grant Access</media:title>
		</media:content>
	</item>
		<item>
		<title>WPD: Transfer Content To A Device</title>
		<link>http://cgeers.com/2012/04/17/wpd-transfer-content-to-a-device/</link>
		<comments>http://cgeers.com/2012/04/17/wpd-transfer-content-to-a-device/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 19:53:01 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[WPD]]></category>
		<category><![CDATA[Windows Portable Devices]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=4070</guid>
		<description><![CDATA[Introduction Mayhap came here sooner than I thought. The previous article on the WPD API dealt with deleting resources. Too destructive perhaps, let&#8217;s create some resources this time. My Kindle&#8217;s is hooked up to my PC. Let&#8217;s see if I can transfer a book to it. Table Of Contents Introduction TransferContentToDevice Method Required Properties Transferring [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4070&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/08/kindle.jpg"><img src="http://cgeers.files.wordpress.com/2011/08/kindle.jpg?w=107&h=150" alt="Kindle" title="Kindle" width="107" height="150" class="alignright size-thumbnail wp-image-3045" /></a></p>
<p>Mayhap came here sooner than I thought. The previous article on the WPD API dealt with deleting resources. Too destructive perhaps, let&#8217;s create some resources this time.</p>
<p>My Kindle&#8217;s is hooked up to my PC. Let&#8217;s see if I can transfer a book to it.</p>
<p><span id="more-4070"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#transfercontenttodevice">TransferContentToDevice Method</a></li>
<li><a href="#requiredproperties">Required Properties</a></li>
<li><a href="#transferringcontent">Transferring Content</a></li>
</ul>
<p><a title="transfercontenttodevice" name="transfercontenttodevice"></a><strong>TransferContentToDevice Method</strong></p>
<p>Get the source code of the fourth article, #69: <a href="http://dl.dropbox.com/u/40603470/WPDDeletingContent.zip" target="_blank">WPD: Deleting Resources</a>, from the <a href="http://cgeers.com/download/" target="_blank">download page</a>. Unzip it and open it up in Visual Studio.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/wpd1.png"><img src="http://cgeers.files.wordpress.com/2012/04/wpd1.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-4076" /></a></p>
<p>In the Solution Explorer select the Program.cs file and open it. Clear the Main(&#8230;) method and add the following code to it.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> devices = <span class="kwrd">new</span> PortableDeviceCollection();
devices.Refresh();
<span class="kwrd">var</span> kindle = devices.First();
kindle.Connect();

kindle.TransferContentToDevice(
    <span class="str">@"d:\temp\Kindle_Users_Guide.azw"</span>,
    <span class="str">@"g:\documents"</span>);

kindle.Disconnect();</pre>
</div>
<p>First we establish a connection to the Kindle, copy the book to it and finally disconnect from it</p>
<p>The magic happens in the TransferContentToDevice(&#8230;) method, which takes two parameters:</p>
<ul>
<li><strong>fileName</strong>: Full path of the file which you want to copy to the device</li>
<li><strong>parentObjectId</strong>: The ID of the parent folder into which you want to copy the file</li>
</ul>
<p>Modify the values of these parameters to suit your situation.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="requiredproperties" name="requiredproperties"></a><strong>Required Properties</strong></p>
<p>Before we can start to implement the TransferContentToDevice(&#8230;) method we first need to add another private method to the PortableDevice class type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> IPortableDeviceValues GetRequiredPropertiesForContentType(
    <span class="kwrd">string</span> fileName,
    <span class="kwrd">string</span> parentObjectId)
{
    <span class="rem">//...</span>
}</pre>
</div>
<p>Before you can upload a resource to a device you need to collect some information about it. This information is stored in a <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd319461(v=vs.85).aspx" target="_blank">IPortableDeviceValu</a>es collection. </p>
<p>Depending on the resource type you may need to collect more data (or properties) that describe the resource. Keep that it mind, the number of required properties might differ for your situation.</p>
<p>For adding a book to a Kindle you need to know the following information:</p>
<ul>
<li><strong>WPD_OBJECT_PARENT_ID</strong>: The ID of the folder into which you want to upload the resource</li>
<li><strong>WPD_OBJECT_SIZE</strong>: The size of the object (in bytes)</li>
<li><strong>WPD_OBJECT_ORIGINAL_FILE_NAME</strong>: The original filename of the object</li>
<li><strong>WPD_OBJECT_NAME</strong>: The name of the object as you wish to represent it on the device</li>
</ul>
<p>Time to implement the method. First you need to create a IPortableDeviceValues collection.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
IPortableDeviceValues values = 
    <span class="kwrd">new</span> PortableDeviceTypesLib.PortableDeviceValues() <span class="kwrd">as</span> IPortableDeviceValues;</pre>
</div>
<p>Then you can add the WPD_OBJECT_PARENT_ID to the collection:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> WPD_OBJECT_PARENT_ID = <span class="kwrd">new</span> _tagpropertykey();
WPD_OBJECT_PARENT_ID.fmtid = 
    <span class="kwrd">new</span> Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
                0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
WPD_OBJECT_PARENT_ID.pid = 3 ;
values.SetStringValue(<span class="kwrd">ref</span> WPD_OBJECT_PARENT_ID, parentObjectId);</pre>
</div>
<p>Adding the rest of the properties is similar.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
FileInfo fileInfo = <span class="kwrd">new</span> FileInfo(fileName);
<span class="kwrd">var</span> WPD_OBJECT_SIZE = <span class="kwrd">new</span> _tagpropertykey();
WPD_OBJECT_SIZE.fmtid = 
    <span class="kwrd">new</span> Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
                0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
WPD_OBJECT_SIZE.pid = 11;            
values.SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, (<span class="kwrd">ulong</span>) fileInfo.Length);

<span class="kwrd">var</span> WPD_OBJECT_ORIGINAL_FILE_NAME = <span class="kwrd">new</span> _tagpropertykey();
WPD_OBJECT_ORIGINAL_FILE_NAME.fmtid = 
    <span class="kwrd">new</span> Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
                0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
WPD_OBJECT_ORIGINAL_FILE_NAME.pid = 12;
values.SetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, Path.GetFileName(fileName));

<span class="kwrd">var</span> WPD_OBJECT_NAME = <span class="kwrd">new</span> _tagpropertykey();
WPD_OBJECT_NAME.fmtid = 
    <span class="kwrd">new</span> Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
                0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);
WPD_OBJECT_NAME.pid = 4;
values.SetStringValue(WPD_OBJECT_NAME, Path.GetFileName(fileName));</pre>
</div>
<p><strong>Remark</strong>: To keep it easy I extracted the filename and path of the book and used that to set both the WPD_OBJECT_ORIGINAL_FILE_NAME and WPD_OBJECT_NAME properties.</p>
<p>Last but not least, don&#8217;t forget to return the collection.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">return</span> values;</pre>
</div>
<p><a href="#top">Top of page</a></p>
<p><a title="transferringcontent" name="transferringcontent"></a><strong>Transferring Content</strong></p>
<p>Now that you can gather all the required properties you can start transferring content to the device. Let&#8217;s implement the TransferContentToDevice(&#8230;) method.</p>
<p>Get an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388529(v=vs.85).aspx" target="_blank">IPortableDeviceContent</a> interface to access resource specific methods.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
IPortableDeviceContent content;
<span class="kwrd">this</span>._device.Content(<span class="kwrd">out</span> content);</pre>
</div>
<p>Now using the GetRequiredPropertiesForContentType(&#8230;) method retrieve the required properties for the resource you want to upload.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
IPortableDeviceValues values =
    GetRequiredPropertiesForContentType(fileName, parentObjectId);</pre>
</div>
<p>Then get an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388542(v=vs.85).aspx" target="_blank">IStream</a> and the optimal buffer size to transfer the resource. This can be done by using the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388534(v=vs.85).aspx" target="_blank">CreateObjectWithPropertiesAndData</a>(&#8230;) method of the IPortableDeviceContent instance.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
PortableDeviceApiLib.IStream tempStream;
<span class="kwrd">uint</span> optimalTransferSizeBytes = 0;
content.CreateObjectWithPropertiesAndData(
    values,
    <span class="kwrd">out</span> tempStream,
    <span class="kwrd">ref</span> optimalTransferSizeBytes,
    <span class="kwrd">null</span>);      </pre>
</div>
<p>Convert the IStream to an <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comtypes.istream.aspx" target="_blank">System.Runtime.InteropService.ComTypes.IStream</a>.<br />
<a href="#top">Top of page</a></p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
System.Runtime.InteropServices.ComTypes.IStream targetStream = 
    (System.Runtime.InteropServices.ComTypes.IStream) tempStream;</pre>
</div>
<p>All that remains is to open a FileStream, read the source file and write it to the target stream. Make sure you close the IStream afterwards (try&#8230;finally).</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">try</span>
{
    <span class="kwrd">using</span> (<span class="kwrd">var</span> sourceStream = 
        <span class="kwrd">new</span> FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        <span class="kwrd">var</span> buffer = <span class="kwrd">new</span> <span class="kwrd">byte</span>[optimalTransferSizeBytes];
        <span class="kwrd">int</span> bytesRead;
        <span class="kwrd">do</span>
        {
            bytesRead = sourceStream.Read(
                buffer, 0, (<span class="kwrd">int</span>)optimalTransferSizeBytes);
            IntPtr pcbWritten = IntPtr.Zero;
            targetStream.Write(
                buffer, (<span class="kwrd">int</span>)optimalTransferSizeBytes, pcbWritten);
        } while (bytesRead &gt; 0);
    }
    targetStream.Commit(0);
}
<span class="kwrd">finally</span>
{
    Marshal.ReleaseComObject(tempStream);
}</pre>
</div>
<p>And that is all she wrote. As always it&#8217;s best to backup your resources before you start experimenting with this code! You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>, <a href='http://cgeers.com/category/programming/wpd/'>WPD</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/4070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/4070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/4070/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4070&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/04/17/wpd-transfer-content-to-a-device/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/08/kindle.jpg?w=107" medium="image">
			<media:title type="html">Kindle</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/wpd1.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>
	</item>
		<item>
		<title>WPD: Deleting Resources</title>
		<link>http://cgeers.com/2012/04/15/wpd-deleting-resources/</link>
		<comments>http://cgeers.com/2012/04/15/wpd-deleting-resources/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 09:32:23 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[WPD]]></category>
		<category><![CDATA[Windows Portable Devices]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=4035</guid>
		<description><![CDATA[Introduction Last year I wrote three articles about the Windows Portable Devices (WDP) API, namely: Enumerating Windows Portable Devices WPD: Enumerating Content WPD: Transferring Content Regularly I get questions asking me how to add or delete resources from a WPD compatible device. Let&#8217;s focus on removing resources first. Mayhap I&#8217;ll write another post about adding [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4035&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/08/kindle.jpg"><img src="http://cgeers.files.wordpress.com/2011/08/kindle.jpg?w=107&h=150" alt="Kindle" title="Kindle" width="107" height="150" class="alignright size-thumbnail wp-image-3045" /></a></p>
<p>Last year I wrote three articles about the <a href="http://cgeers.com/category/programming/wpd/" target="_blank">Windows Portable Devices (WDP) API</a>, namely:</p>
<ul>
<li><a href="http://cgeers.com/2011/05/22/enumerating-windows-portable-devices/" target="_blank">Enumerating Windows Portable Devices</a></li>
<li><a href="http://cgeers.com/2011/06/05/wpd-enumerating-content/" target="_blank">WPD: Enumerating Content</a></li>
<li><a href="http://cgeers.com/2011/08/13/wpd-transferring-content/" target="_blank">WPD: Transferring Content</a></li>
</ul>
<p>Regularly I get questions asking me how to add or delete resources from a WPD compatible device. Let&#8217;s focus on removing resources first. Mayhap I&#8217;ll write another post about adding resources next time.</p>
<p>I&#8217;m going to connect my Kindle and see if I can&#8217;t delete a book from it.</p>
<p><span id="more-4035"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#source">Source Code</a></li>
<li><a href="#content">Content</a></li>
<li><a href="#what">What to delete?</a></li>
<li><a href="#deletingresources">Deleting Resources</a></li>
</ul>
<p><a title="source" name="source"></a><strong>Source Code</strong></p>
<p>If you haven&#8217;t read the previous articles of this series yet, then do so now or at least have a quick glance at them. Go to the <a href="http://cgeers.com/download/" target="_blank">download page</a> and download the source code of the third one, Article #53: WPD: Transferring Content.</p>
<p>Start Visual Studio and open the downloaded solution.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/wpd.png"><img src="http://cgeers.files.wordpress.com/2012/04/wpd.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-4041" /></a></p>
<p>Open the Program.cs code file and delete everything, but leave an empty Main() method. We want to start with a clean slate.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="content" name="content"></a><strong>Content</strong></p>
<p>Before we start deleting resources, let&#8217;s first find out what is stored on the device. Let&#8217;s establish a connection with the device.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> devices = <span class="kwrd">new</span> PortableDeviceCollection();
devices.Refresh();
<span class="kwrd">var</span> kindle = devices.First();
kindle.Connect();
</pre>
</div>
<p>Now let&#8217;s retrieve the resources of the root folder and enumerate over them.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> root = kindle.GetContents();
<span class="kwrd">foreach</span> (<span class="kwrd">var</span> resource <span class="kwrd">in</span> root.Files)
{
    DisplayResourceContents(resource);
}</pre>
</div>
<p>Each resource located in the root can either be a file or another folder. The DisplayResourceContents(&#8230;) methods displays the resource&#8217;s name and if it&#8217;s a folder it lists its contents.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> DisplayResourceContents(
    PortableDeviceObject portableDeviceObject)
{
    Console.WriteLine(portableDeviceObject.Name);
    <span class="kwrd">if</span> (portableDeviceObject <span class="kwrd">is</span> PortableDeviceFolder)
    {
        DisplayFolderContents((PortableDeviceFolder) portableDeviceObject);
    }
}</pre>
</div>
<p>The DisplayFolderContents(&#8230;) method is a recursive methods which drills down all the subfolders.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> DisplayFolderContents(
    PortableDeviceFolder folder)
{
    <span class="kwrd">foreach</span> (<span class="kwrd">var</span> item <span class="kwrd">in</span> folder.Files)
    {
        Console.WriteLine(item.Id);

        <span class="kwrd">if</span> (item <span class="kwrd">is</span> PortableDeviceFolder)
        {
            DisplayFolderContents((PortableDeviceFolder) item);
        }
    }
}</pre>
</div>
<p>If you run the code now, you&#8217;ll get a list of all the resources which are stored on your device. Or in my case, a list of the books stored on my Kindle.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/04/wpd2.png"><img src="http://cgeers.files.wordpress.com/2012/04/wpd2.png?w=480&h=242" alt="WPD Resources" title="WPD Resources" width="480" height="242" class="aligncenter size-full wp-image-4048" /></a></p>
<p>The PortableDeviceCollection, PortableDeviceObject, PortableDeviceFolder &#8230; types which I used here are wrappers around types such as PortableDeviceManager imported from the “PortableDeviceApi 1.0 Type Library″ and “PortableDeviceTypes 1.0 Type Library” COM libraries. Take a look at the second article of this series, <a href="http://cgeers.com/2011/06/05/wpd-enumerating-content/" target="_blank">WPD: Enumerating Content</a>, for a more in-depth explanation on how to enumerate the resources on your device.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="what" name="what"></a><strong>What to delete?</strong></p>
<p>Before you can delete a resource you need to get a hold of its ID. Each file or folder has a unique ID.</p>
<p>Here I execute a naive LINQ query which selects the documents folder from the Kindle.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
PortableDeviceFolder documents =
    (<span class="kwrd">from</span> r <span class="kwrd">in</span> ((PortableDeviceFolder)root.Files[0]).Files
     where r.Name.Contains(<span class="str">"documents"</span>)
     select r).First() <span class="kwrd">as</span> PortableDeviceFolder;</pre>
</div>
<p>Let&#8217;s delete the Users Guide, I&#8217;m not going to read it. Start Kindle, select book, click next or previous&#8230;how difficult can it be. </p>
<p>The book is made up out of two resources. A *.azw (<a href="http://wiki.mobileread.com/wiki/AZW" target="_blank">Amazon Word</a>) and a *.mbp file (contains bookmarks, annotations, last read page&#8230;etc).</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> books = <span class="kwrd">from</span> b <span class="kwrd">in</span> documents.Files
            where b.Name.Contains(<span class="str">"Kindle_Users_Guide"</span>)
            select b;
</pre>
</div>
<p>And their IDs are:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">foreach</span> (PortableDeviceFile book <span class="kwrd">in</span> books)
{
    Console.WriteLine(book.Id);
}</pre>
</div>
<p><a href="http://cgeers.files.wordpress.com/2012/04/wpd3.png"><img src="http://cgeers.files.wordpress.com/2012/04/wpd3.png?w=480&h=89" alt="Kindle Users Guide Files" title="Kindle Users Guide Files" width="480" height="89" class="aligncenter size-full wp-image-4056" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="deletingresources" name="deletingresources"></a><strong>Deleting Resources</strong></p>
<p>Time to delete the users guide. Open the PortableDevice.cs code file and add a new method called DeleteFile(&#8230;) to the PortableDevice class.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> <span class="kwrd">void</span> DeleteFile(PortableDeviceFile file)
{
    <span class="rem">//...</span>
}</pre>
</div>
<p>First you need to get an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388529(v=vs.85).aspx" target="_blank">IPortableDeviceContent</a> instance with which you can create, enumerate, examine and delete content on a device.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
IPortableDeviceContent content;
<span class="kwrd">this</span>._device.Content(<span class="kwrd">out</span> content);</pre>
</div>
<p>Next you need to identify the resource which you want to delete. IPortableDeviceContent offers a Delete(&#8230;) method which requires an <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388719(v=vs.85).aspx" target="_blank">IPortableDevicePropVariantCollection</a>. This interface holds a collection of PROPVARIANT values which identify the resources to delete.</p>
<p>You need to convert the ID of the resource, which is a string, to a PROPVARIANT. The PROPVARIANT is represented by the tag_inner_PROPVARIANT type found in the imported PortableDeviceApiLib COM library. Luckily one member of the WPD team explained how to do this in C# about five years ago.</p>
<p><a href="http://blogs.msdn.com/b/dimeby8/archive/2007/01/08/creating-wpd-propvariants-in-c-without-using-interop.aspx" target="_blank">http://blogs.msdn.com/b/dimeby8/archive/2007/01/08/creating-wpd-propvariants-in-c-without-using-interop.aspx</a></p>
<p>Let&#8217;s borrow his StringToPropVariant method and add it to our PortableDevice class.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> StringToPropVariant(
    <span class="kwrd">string</span> value, 
    <span class="kwrd">out</span> PortableDeviceApiLib.tag_inner_PROPVARIANT propvarValue)
{
    PortableDeviceApiLib.IPortableDeviceValues pValues =
        (PortableDeviceApiLib.IPortableDeviceValues)
            <span class="kwrd">new</span> PortableDeviceTypesLib.PortableDeviceValuesClass();

    <span class="kwrd">var</span> WPD_OBJECT_ID = <span class="kwrd">new</span> _tagpropertykey();
    WPD_OBJECT_ID.fmtid = 
        <span class="kwrd">new</span> Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 
                    0x8B, 0x60, 0xEE, 0x4A, 0x3C);
    WPD_OBJECT_ID.pid = 2;

    pValues.SetStringValue(<span class="kwrd">ref</span> WPD_OBJECT_ID, value);

    pValues.GetValue(<span class="kwrd">ref</span> WPD_OBJECT_ID, <span class="kwrd">out</span> propvarValue);
}</pre>
</div>
<p>Now you can convert the ID of a resource to a PROPVARIANT and add it to a IPortableDevicePropVariantCollection.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> variant = <span class="kwrd">new</span> PortableDeviceApiLib.tag_inner_PROPVARIANT();
StringToPropVariant(file.Id, <span class="kwrd">out</span> variant);

PortableDeviceApiLib.IPortableDevicePropVariantCollection objectIds =
    <span class="kwrd">new</span> PortableDeviceTypesLib.PortableDevicePropVariantCollection() 
    <span class="kwrd">as</span> PortableDeviceApiLib.IPortableDevicePropVariantCollection;
objectIds.Add(variant);</pre>
</div>
<p>The preparations are done and all that remains is to delete the resource. Just call the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd388536(v=vs.85).aspx" target="_blank">IPortableDeviceContent&#8217;s Delete(&#8230;) method</a>.</p>
<p>Pass zero for the first parameter, then the ID&#8217;s (PROPVARIANTs) of the resource you want to delete and ignore the results. We&#8217;ll be naive and hope all goes well. Improve on this if you will and inspect if all went as expected.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
content.Delete(0, objectIds, <span class="kwrd">null</span>);</pre>
</div>
<p>Now you can delete the resources associated with the users guide.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">foreach</span> (PortableDeviceFile book <span class="kwrd">in</span> books)
{
    kindle.DeleteFile(book);
}</pre>
</div>
<p>Voila, that&#8217;s all there is to it. Best to backup your resources before you start experimenting with this code! You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>, <a href='http://cgeers.com/category/programming/wpd/'>WPD</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/4035/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/4035/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/4035/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=4035&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/04/15/wpd-deleting-resources/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/08/kindle.jpg?w=107" medium="image">
			<media:title type="html">Kindle</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/wpd.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/wpd2.png" medium="image">
			<media:title type="html">WPD Resources</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/04/wpd3.png" medium="image">
			<media:title type="html">Kindle Users Guide Files</media:title>
		</media:content>
	</item>
		<item>
		<title>Dropbox REST API Part 6: OAuth Callback</title>
		<link>http://cgeers.com/2012/03/17/dropbox-rest-api-part-6-oauth-callback/</link>
		<comments>http://cgeers.com/2012/03/17/dropbox-rest-api-part-6-oauth-callback/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 12:53:09 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Dropbox API]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=3996</guid>
		<description><![CDATA[Introduction With this entry into the Dropbox series we come back to the beginning of the cycle. We started with authentication and that&#8217;s where we&#8217;ll end. Having a user authorize your application to access his or hers Dropbox account consists out of 3 steps. Using OAuth you must: Retrieve a request token Have the user [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3996&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/12/logo1.png"><img src="http://cgeers.files.wordpress.com/2011/12/logo1.png?w=480" alt="DropBox Logo" title="DropBox Logo"   class="alignright size-full wp-image-3688" /></a></p>
<p>With this entry into the <a href="http://cgeers.com/category/programming/dropbox/" target="_blank">Dropbox series</a> we come back to the beginning of the cycle. We started with <a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/" target="_blank">authentication</a> and that&#8217;s where we&#8217;ll end.</p>
<p>Having a user authorize your application to access his or hers Dropbox account consists out of 3 steps. Using <a href="http://oauth.net/" target="_blank">OAuth</a> you must:</p>
<ol>
<li><a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/#requesttoken" target="_blank">Retrieve a request token</a></li>
<li><a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/#authorize" target="_blank">Have the user authorize your application</a></li>
<li><a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/#accesstoken" target="_blank">Retrieve an access token</a></li>
</ol>
<p>Before retrieving an access token you must wait until the user has authorized your application. There&#8217;s no way to determine when this has happened. Up until now we just waited a little while and hoped for the best. However, when you instruct the user to authorize your application, you can also specify a callback URL which will automatically be called when the authorization process has been completed.</p>
<p>Let&#8217;s create a sample web application that demonstrates this.</p>
<p><span id="more-3996"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#mvctemplate">MVC 3 Template</a></li>
<li><a href="#authorization">Authorization</a></li>
<li><a href="#oauth">OAuth</a></li>
<li><a href="#callback">Callback</a></li>
</ul>
<p><a title="mvctemplate" name="mvctemplate"></a><strong>MVC 3 Template</strong></p>
<p><a href="http://cgeers.com/download/" target="_blank">Download</a> the code of part #5 (article #67), unzip it and open it up in Visual Studio. Add a new MVC 3 web application called &#8220;MvcApplication&#8221; to the solution.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/03/dropbox1.png"><img src="http://cgeers.files.wordpress.com/2012/03/dropbox1.png?w=480&h=137" alt="Add New Project" title="Add New Project" width="480" height="137" class="aligncenter size-full wp-image-4008" /></a></p>
<p>Make sure to select the Internet Application template so that we don&#8217;t have to create a basic layout ourselves.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/03/dropbox2.png"><img src="http://cgeers.files.wordpress.com/2012/03/dropbox2.png?w=480" alt="Project Template" title="Project Template"   class="aligncenter size-full wp-image-4009" /></a></p>
<p>The first thing I did was to remove the about page and everything related to the account pages (login, register&#8230;etc.). You won&#8217;t need them. I just want to get a simple one page site up and running as fast as possible. After removing these unnessary pages, user controls, markup&#8230;etc. You should wind up with a site resembling the following:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/03/dropbox3.png"><img src="http://cgeers.files.wordpress.com/2012/03/dropbox3.png?w=480" alt="MVC Web Application" title="MVC Web Application"   class="aligncenter size-full wp-image-4012" /></a></p>
<p>Feel free to adjust the default messages on the page as you please.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="authorization" name="authorization"></a><strong>Authorization</strong></p>
<p>Let&#8217;s kick off the authorization process. Add a reference to the OAuthProtocol and Dropbox.Api projects. Next add a simple form to the home page (Index.cshtml).</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
@using (Html.BeginForm("AuthorizeDropbox", "Home"))
{
    <span class="kwrd">&lt;</span><span class="html">input</span> <span class="attr">type</span><span class="kwrd">="submit"</span> <span class="attr">value</span><span class="kwrd">="Gimme access to your Dropbox account"</span> <span class="kwrd">/&gt;</span>
}</pre>
</div>
<p>Which results in this cutting edge form:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/03/dropbox4.png"><img src="http://cgeers.files.wordpress.com/2012/03/dropbox4.png?w=480" alt="Web Form" title="Web Form"   class="aligncenter size-full wp-image-4016" /></a></p>
<p>When you submit the form the AuthorizeDropbox() action is executed. Let&#8217;s implement it.</p>
<p>First add your application&#8217;s key and secret to the HomeController class.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> ConsumerKey = <span class="str">"your application key"</span>;
<span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> ConsumerSecret = <span class="str">"your application secret"</span>;</pre>
</div>
<p>Then add the following action to the controller.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> ActionResult AuthorizeDropbox()
{            
    <span class="kwrd">var</span> oauth = <span class="kwrd">new</span> OAuth();
    <span class="kwrd">var</span> requestToken = oauth.GetRequestToken(
        <span class="kwrd">new</span> Uri(DropboxRestApi.BaseUri), ConsumerKey, ConsumerSecret);

    Session[<span class="str">"requestToken"</span>] = requestToken;

    <span class="kwrd">var</span> action = Url.Action(<span class="str">"Authorized"</span>, <span class="str">"Home"</span>, <span class="kwrd">null</span>, Request.Url.Scheme);
    <span class="kwrd">var</span> callbackUri = <span class="kwrd">new</span> Uri(action);            

    <span class="kwrd">var</span> authorizeUri = oauth.GetAuthorizeUri(
        <span class="kwrd">new</span> Uri(DropboxRestApi.AuthorizeBaseUri), requestToken, callbackUri);

    <span class="kwrd">return</span> Redirect(authorizeUri.ToString());
}</pre>
</div>
<p>First you retrieve a request token and temporarily store it in the session state. Next you compose the callback URL which is automatically called after the user has authorized your application. The callback should resemble something like this:</p>
<p><a href="http://localhost:53291/Home/Authorized" target="_blank">http://localhost:53291/Home/Authorized</a></p>
<p>Last, but not least you retrieve the authorization URL and redirect the user to it so he can start the authorization process. The user will now be redirected to his Dropbox account where he&#8217;ll have to login and get a chance to authorize your application.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="oauth" name="oauth"></a><strong>OAuth</strong></p>
<p>If you compile now you should get some compiler errors. You&#8217;ll need to modify the OAuth type located in the OAuthProtocol project slightly. Open OAuth.cs code file and add an extra parameter (callbackUrl) to GetAuthorizeUri(&#8230;) method.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> Uri GetAuthorizeUri(Uri baseUri, OAuthToken requestToken, Uri callbackUrl)
{
    <span class="rem">//...</span>
}</pre>
</div>
<p>Now you need to modify the implementation of this method. It&#8217;s really simple actually. If a callback URL is specified, just append it to the query string.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> queryString = String.Format(<span class="str">"oauth_token={0}"</span>, 
    requestToken.Token);
<span class="kwrd">if</span> (callbackUrl != <span class="kwrd">null</span>)
{
    queryString = String.Format(<span class="str">"{0}&amp;&amp;oauth_callback={1}"</span>, 
        queryString, callbackUrl);
}
<span class="kwrd">var</span> authorizeUri = String.Format(<span class="str">"{0}{1}?{2}"</span>, baseUri, 
    <span class="str">"oauth/authorize"</span>, queryString);
<span class="kwrd">return</span> <span class="kwrd">new</span> Uri(authorizeUri);</pre>
</div>
<p>And for good measure let&#8217;s add an overload, so that the existing code (which is not expecting this extra parameter) doesn&#8217;t break.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> Uri GetAuthorizeUri(Uri baseUri, OAuthToken requestToken)
{
    <span class="kwrd">return</span> GetAuthorizeUri(baseUri, requestToken, <span class="kwrd">null</span>);
}</pre>
</div>
<p><a href="#top">Top of page</a></p>
<p><a title="callback" name="callback"></a><strong>Callback</strong></p>
<p>If you specified a callback URL then the user will be redirected here once he has authorized your application. Dropbox will provide a couple of values via GET parameters in the URL:</p>
<ul>
<li><strong>oauth_token</strong>: The request token that was just authorized.</li>
<li><strong>uid</strong>: The user&#8217;s unique Dropbox ID.
</li>
</ul>
<p>Let&#8217;s add an action to the home controller so that we can handle the callback.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> ActionResult Authorized(<span class="kwrd">string</span> oauth_token, <span class="kwrd">string</span> uid)
{
   <span class="rem">//...</span>
}</pre>
<p>The implementation is straight forward.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> requestToken = (OAuthToken) Session[<span class="str">"requestToken"</span>];

<span class="kwrd">var</span> oauth = <span class="kwrd">new</span> OAuth();
            
<span class="kwrd">var</span> accessToken = oauth.GetAccessToken(
    <span class="kwrd">new</span> Uri(DropboxRestApi.BaseUri), ConsumerKey, ConsumerSecret, requestToken);

ViewBag.UserId = uid;
ViewBag.AccessToken = accessToken;

<span class="kwrd">return</span> View();</pre>
</div>
<p>First you need to retrieve the request token / secret from the session state. Then you can retrieve an access token. You need to store this access token somewhere, so that you can use it next time instead of forcing the user to follow the entire authorization process again. </p>
<p>To finish this sample I just display a simple view which lists the access token. But ofcourse, what you do once you&#8217;ve got access to the user&#8217;s Dropbox account is up to you.</p>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></div>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/dropbox/'>Dropbox</a>, <a href='http://cgeers.com/category/programming/oauth/'>OAuth</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/3996/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/3996/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/3996/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3996&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/03/17/dropbox-rest-api-part-6-oauth-callback/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/12/logo1.png" medium="image">
			<media:title type="html">DropBox Logo</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/03/dropbox1.png" medium="image">
			<media:title type="html">Add New Project</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/03/dropbox2.png" medium="image">
			<media:title type="html">Project Template</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/03/dropbox3.png" medium="image">
			<media:title type="html">MVC Web Application</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/03/dropbox4.png" medium="image">
			<media:title type="html">Web Form</media:title>
		</media:content>
	</item>
		<item>
		<title>Dropbox REST API Part 5: File Upload</title>
		<link>http://cgeers.com/2012/03/11/dropbox-rest-api-part-5-file-upload/</link>
		<comments>http://cgeers.com/2012/03/11/dropbox-rest-api-part-5-file-upload/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 09:54:51 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Dropbox API]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=3965</guid>
		<description><![CDATA[Introduction In the last part of the Dropbox series, we handled file downloads. This time I&#8217;ll show you how you can easily upload files to your Dropbox account. To follow along, download the code of part #4 (article 66) from the download page, unzip it and open the solution in Visual Studio. Let&#8217;s get started&#8230; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3965&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/12/logo1.png"><img src="http://cgeers.files.wordpress.com/2011/12/logo1.png?w=480" alt="DropBox Logo" title="DropBox Logo"   class="alignright size-full wp-image-3688" /></a></p>
<p>In the last part of the <a href="http://cgeers.com/category/programming/dropbox/" target="_blank">Dropbox series</a>, we handled file downloads. This time I&#8217;ll show you how you can easily upload files to your Dropbox account.</p>
<p>To follow along, download the code of part #4 (article 66) from the <a href="http://cgeers.com/download/" target="_blank">download page</a>, unzip it and open the solution in Visual Studio.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/03/dropbox.png"><img src="http://cgeers.files.wordpress.com/2012/03/dropbox.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-3974" /></a></p>
<p>Let&#8217;s get started&#8230;</p>
<p><span id="more-3965"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#urlencoding">URL Encoding</a></li>
<li><a href="#upload">Uploading a File</a></li>
</ul>
<p><a title="urlencoding" name="urlencoding"></a><strong>URL Encoding</strong></p>
<p>Before we continue, I want to address an issue that was brought to my attention in the comments of the previous parts. A lot of methods of the Dropbox API require that you pass a path parameter which represents the file you want to upload, download, rename&#8230;etc. This path parameters needs to be URL encoded correctly.</p>
<p>I use the <a href="http://msdn.microsoft.com/en-us/library/4fkewx0t.aspx" target="_blank">HttpUtility.UrlEncode</a>(&#8230;) method to encode the paths. However as I mentioned in the <a href="http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/#encoding" target="_blank">3rd part</a>, there is a problem with this method. Slashes (/) are translated to %2f, while Dropbox expects it to be all uppercase. That&#8217;s why I added the (private) UpperCaseUrlEncode(&#8230;) method to the DropboxApi type. It uses the HttpUtility.UrlEncode(&#8230;) method to encode the path, but it makes sure the escaped characters are uppercased.</p>
<p>Turns out that .NET’s HttpUtility.UrlEncode(…) does not follow the RFC3986:</p>
<p><a href="http://www.faqs.org/rfcs/rfc3986.html" target="_blank">http://www.faqs.org/rfcs/rfc3986.html</a></p>
<p>For instance, one thing that it does differently is to encode spaces as &#8216;+&#8217; signs instead of using &#8216;%20&#8242;.</p>
<p>In PHP they have two functions for this <a href="http://www.php.net/manual/en/function.urlencode.php" target="_blank">urlencode</a> and <a href="http://www.php.net/manual/en/function.rawurlencode.php" target="_blank">rawurlencode</a>. I could not find a substitue for the rawurlencode method in the .NET framework. So we need to modify the UpperCaseUrlEncode(&#8230;) method.</p>
<p>It&#8217;s not just spaces that caused problems, brackets &#8220;(&#8221; &amp; &#8220;)&#8221; were also incorrectly escaped. ( should become %28, and ) should become %29.</p>
<p>Let&#8217;s fix this to make sure the &#8216;+&#8217; signs (spaces), bracketes&#8230;etc. are correctly encoded. </p>
<p>At the end of the method I compose a dictionary of characters and their percent encoding equivalent. Next I do a &#8220;manual&#8221; replace of those characters.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">string</span> UpperCaseUrlEncode(<span class="kwrd">string</span> s)
{
    <span class="kwrd">char</span>[] temp = HttpUtility.UrlEncode(s).ToCharArray();
    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; temp.Length - 2; i++)
    {
        <span class="kwrd">if</span> (temp[i] == <span class="str">'%'</span>)
        {
            temp[i + 1] = <span class="kwrd">char</span>.ToUpper(temp[i + 1]);
            temp[i + 2] = <span class="kwrd">char</span>.ToUpper(temp[i + 2]);
        }
    }

    <span class="kwrd">var</span> values = <span class="kwrd">new</span> Dictionary&lt;<span class="kwrd">string</span>, <span class="kwrd">string</span>&gt;()
    {
        { <span class="str">"+"</span>, <span class="str">"%20"</span> },
        { <span class="str">"("</span>, <span class="str">"%28"</span> },
        { <span class="str">")"</span>, <span class="str">"%29"</span> }
    };

    <span class="kwrd">var</span> data = <span class="kwrd">new</span> StringBuilder(<span class="kwrd">new</span> <span class="kwrd">string</span>(temp));
    <span class="kwrd">foreach</span> (<span class="kwrd">string</span> character <span class="kwrd">in</span> values.Keys)
    {
        data.Replace(character, values[character]);
    }
    <span class="kwrd">return</span> data.ToString();
}</pre>
</div>
<p>Now it correctly encodes the spaces and brackets. If any more characters should cause problems you just need to add them to the values dictionary.</p>
<p>Take a look at percent encoding for more information:</p>
<p><a href="http://en.wikipedia.org/wiki/Percent-encoding" target="_blank">http://en.wikipedia.org/wiki/Percent-encoding</a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="upload" name="upload"></a><strong>Uploading a File</strong></p>
<p>Open the DropboxApi.cs code file (Dropbox.Api project) and add the following method to the DropboxApi type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> FileSystemInfo UploadFile(<span class="kwrd">string</span> root, <span class="kwrd">string</span> path, <span class="kwrd">string</span> file)
{
  <span class="rem">//...</span>
}</pre>
</div>
<p>The method has 3 parameters:</p>
<ul>
<li><strong>root</strong>: The root relative to which the path is specified. Valid values are sandbox and dropbox.</li>
<li><strong>path</strong>: The path to the file you want to upload.</li>
<li><strong>file</strong>: Absolute path to the local file you want to upload</li>
</ul>
<p>You can call this new method as follows:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> file = api.UploadFile(<span class="str">"dropbox"</span>, <span class="str">"photo.jpg"</span>, <span class="str">@"C:\Pictures\photo.jpg"</span>);</pre>
</div>
<p>Let&#8217;s implement the method. First let&#8217;s compose the URL of the Dropbox API which we&#8217;ll need to call.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> uri = <span class="kwrd">new</span> Uri(<span class="kwrd">new</span> Uri(DropboxRestApi.ApiContentServer),
    String.Format(<span class="str">"files_put/{0}/{1}"</span>,
    root, UpperCaseUrlEncode(path)));</pre>
</div>
<p>This will give you the following URI:</p>
<p><a href="https://api-content.dropbox.com/1/files_put/dropbox/photo.jpg" target="_blank">https://api-content.dropbox.com/1/files_put/dropbox/photo.jpg</a></p>
<p>Next we need to sign this request using our little OAuth library.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> oauth = <span class="kwrd">new</span> OAuth();   
<span class="kwrd">var</span> requestUri = oauth.SignRequest(uri, 
    _consumerKey, _consumerSecret, _accessToken, <span class="str">"PUT"</span>);</pre>
</div>
<p><strong>Remark</strong>: For file uploads you need to use PUT semantics. You also need to specify this when signing the request. The OAuth code will use GET by default, this will result in an invalid signature and Dropbox will return a 403 Forbidden error. I modified the OAuth code a bit so that you can specify the HTTP method when signing a request. Check out the source code if you want to explore that part further.</p>
<p>Let&#8217;s create a request.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> request = (HttpWebRequest) WebRequest.Create(requestUri);
request.Method = WebRequestMethods.Http.Put;
request.KeepAlive = <span class="kwrd">true</span>;</pre>
</div>
<p>Now for the easy part, let&#8217;s read the source file into a byte array.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">byte</span>[] buffer;
<span class="kwrd">using</span> (<span class="kwrd">var</span> fileStream = <span class="kwrd">new</span> FileStream(
    file, FileMode.Open, FileAccess.Read))
{
    <span class="kwrd">int</span> length = (<span class="kwrd">int</span>) fileStream.Length;
    buffer = <span class="kwrd">new</span> <span class="kwrd">byte</span>[length];
    fileStream.Read(buffer, 0, length);
}</pre>
</div>
<p>Now you need to write this byte array to the request stream of the request.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
request.ContentLength = buffer.Length;
<span class="kwrd">using</span> (<span class="kwrd">var</span> requestStream = request.GetRequestStream())
{
    requestStream.Write(buffer, 0, buffer.Length);
}</pre>
</div>
<p>Voila, the request has been prepared. Time to send it and parse the response. Dropbox returns metadata for the uploaded file. We can deserialize this data (JSON) into our existing FileSystemInfo type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> response = request.GetResponse();
<span class="kwrd">var</span> reader = <span class="kwrd">new</span> StreamReader(response.GetResponseStream());
<span class="kwrd">var</span> json = reader.ReadToEnd();
<span class="kwrd">return</span> ParseJson&lt;FileSystemInfo&gt;(json);</pre>
</div>
<p>See how easy that was? Now you can upload a file using two lines of code.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> api = <span class="kwrd">new</span> DropboxApi(ConsumerKey, ConsumerSecret, accessToken);
<span class="kwrd">var</span> file = api.UploadFile(<span class="str">"dropbox"</span>, <span class="str">"photo.jpg"</span>, <span class="str">@"c:\pictures\photo.jpg"</span>);</pre>
</div>
<p>Check out the Dropbox REST API documentation if you want to explore it further and implement new features.</p>
<p><a href="https://www.dropbox.com/developers/reference/api" target="_blank">https://www.dropbox.com/developers/reference/api</a></p>
<p>In part 6 I’ll come back to authentication and show you how you can implement a callback mechanism. This way Dropbox lets you know when the user has authorized your application. </p>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/dropbox/'>Dropbox</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/3965/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/3965/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/3965/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3965&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/03/11/dropbox-rest-api-part-5-file-upload/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/12/logo1.png" medium="image">
			<media:title type="html">DropBox Logo</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/03/dropbox.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>
	</item>
		<item>
		<title>Dropbox REST API Part 4: Download a File</title>
		<link>http://cgeers.com/2012/02/26/dropbox-rest-api-part-4-download-a-file/</link>
		<comments>http://cgeers.com/2012/02/26/dropbox-rest-api-part-4-download-a-file/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 12:20:11 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Dropbox API]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=3932</guid>
		<description><![CDATA[Introduction So far we&#8217;ve covered the following topics in the Dropbox series: Part 1: Authentication Part 2: API Requests Part 3: Create, Delete and Move Folders Once you are authenticated you can make API requests such as requesting your account information, creating, deleting folders&#8230;etc. One particular type of request is downloading a file from your [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3932&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/12/logo1.png"><img src="http://cgeers.files.wordpress.com/2011/12/logo1.png?w=480" alt="DropBox Logo" title="DropBox Logo"   class="alignright size-full wp-image-3688" /></a></p>
<p>So far we&#8217;ve covered the following topics in the Dropbox series:</p>
<ul>
<li><a href="http://cgeers.com/2011/12/29/dropbox-rest-api-part-1-authentication/" target="_blank">Part 1: Authentication</a></li>
<li><a href="http://cgeers.com/2012/01/08/dropbox-rest-api-part-2-api-requests/" target="_blank">Part 2: API Requests</a></li>
<li><a href="http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/" target="_blank">Part 3: Create, Delete and Move Folders</a></li>
</ul>
<p>Once you are authenticated you can make API requests such as requesting your account information, creating, deleting folders&#8230;etc. One particular type of request is downloading a file from your Dropbox account. Once you&#8217;ve worked your way through the previous 3 parts this becomes trivially easy. </p>
<p>If you want to follow along go to the <a href="http://cgeers.com/download/" target="_blank">download page</a> and download the code for the third part (article #65). Unzip it and open it up in Visual Studio.</p>
<p><span id="more-3932"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#newmethod">A New Method</a></li>
<li><a href="#filesysteminfo">Expanding FileSystemInfo</a></li>
<li><a href="#download">Downloading the File</a></li>
</ul>
<p><a title="newmethod" name="newmethod"></a><strong>A New Method</strong></p>
<p>Let&#8217;s add a new method to the DropboxApi type called DownloadFile(&#8230;).</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> FileSystemInfo DownloadFile(<span class="kwrd">string</span> root, <span class="kwrd">string</span> path)
{
    <span class="rem">// ...</span>
}</pre>
</div>
<p>It takes two parameters, namely:</p>
<ul>
<li><strong>root</strong>: The root relative to which the path is specified. Valid values are sandbox and dropbox.</li>
<li><strong>path</strong>: The path to the file you want to download.</li>
</ul>
<p>It returns an instance of the <a href="http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/#create" target="_blank">FileSystemInfo type</a>, which we created earlier in part #3. The FileSystemInfo type contains the file&#8217;s metadata.</p>
<p>Example usage of the new method:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> api = <span class="kwrd">new</span> DropboxApi(ConsumerKey, ConsumerSecret, accessToken);
<span class="kwrd">var</span> file = api.DownloadFile(<span class="str">"dropbox"</span>, <span class="str">"Public/DropboxPart3.zip"</span>);
file.Save(<span class="str">@"C:\DropboxPart3.zip"</span>);</pre>
</div>
<p><a href="#top">Top of page</a></p>
<p><a title="filesysteminfo" name="filesysteminfo"></a><strong>Expanding FileSystemInfo </strong></p>
<p>Before we can proceed we need to modify the existing FileSystemInfo type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> <span class="kwrd">class</span> FileSystemInfo
{
    <span class="rem">//...</span>

    <span class="kwrd">public</span> <span class="kwrd">byte</span>[] Data { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    <span class="kwrd">public</span> <span class="kwrd">void</span> Save(<span class="kwrd">string</span> path)
    {
        <span class="kwrd">using</span> (<span class="kwrd">var</span> fileStream = <span class="kwrd">new</span> FileStream(
            path, FileMode.Create, FileAccess.ReadWrite))
        {
            fileStream.Write(Data, 0, Data.Length);
        }            
    }
}</pre>
</div>
<p>The new property Data returns a byte array which contains the contents of the file we downloaded. The Save(&#8230;) method allows you to easily save the file. No world shocking news here.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="download" name="download"></a><strong>Downloading the File</strong></p>
<p>Let&#8217;s implement the DownloadFile(&#8230;) method. When downloading a file we need to contact the API content server. So let&#8217;s add a URL to the DropboxRestApi type.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> <span class="kwrd">class</span> DropboxRestApi
{
    <span class="kwrd">public</span> <span class="kwrd">const</span> <span class="kwrd">string</span> ApiVersion = <span class="str">"1"</span>;

    <span class="kwrd">public</span> <span class="kwrd">const</span> <span class="kwrd">string</span> ApiContentServer = 
        <span class="str">"https://api-content.dropbox.com/"</span> + ApiVersion + <span class="str">"/"</span>;

    <span class="rem">//...</span>
}</pre>
</div>
<p>Now we can start with implementing the DownloadFile(&#8230;) method. First we need to compose a URL for the file which we want to retrieve.</p>
<p>For example:</p>
<p><a href="https://api-content.dropbox.com/1/files?root=dropbox&amp;path=Public/DropboxPart3.zip" target="_blank">https://api-content.dropbox.com/1/files?root=dropbox&amp;path=Public/DropboxPart3.zip</a></p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> uri = <span class="kwrd">new</span> Uri(<span class="kwrd">new</span> Uri(DropboxRestApi.ApiContentServer),
    String.Format(<span class="str">"files?root={0}&amp;path={1}"</span>,
    root, UpperCaseUrlEncode(path)));</pre>
</div>
<p><strong>Remark</strong>: We created the <a href="http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/#encoding" target="_blank">UpperCaseUrlEncode(&#8230;) method</a> last time to circumvent a rather annoying problem when URL encoding the path.</p>
<p>Next we need to sign the request.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
<span class="kwrd">var</span> oauth = <span class="kwrd">new</span> OAuth();
<span class="kwrd">var</span> requestUri = oauth.SignRequest(uri, _consumerKey, _consumerSecret, 
    _accessToken);</pre>
</div>
<p>Then you can finally execute a GET request to download the file.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> request = (HttpWebRequest) WebRequest.Create(requestUri);
request.Method = WebRequestMethods.Http.Get;
<span class="kwrd">var</span> response = request.GetResponse();</pre>
</div>
<p>The HTTP response contains the file&#8217;s metadata in JSON format within an x-dropbox-metadata header. Let&#8217;s extract this metadata from the headers and deserialize it into a FileSystemInfo instance.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> metadata = response.Headers[<span class="str">"x-dropbox-metadata"</span>];
<span class="kwrd">var</span> file = ParseJson&lt;FileSystemInfo&gt;(metadata);</pre>
</div>
<p>Now we can read the response and store the file as a byte array in the FileSystemInfo instance.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">using</span> (Stream responseStream = response.GetResponseStream())
<span class="kwrd">using</span> (MemoryStream memoryStream = <span class="kwrd">new</span> MemoryStream())
{
    <span class="kwrd">byte</span>[] buffer = <span class="kwrd">new</span> <span class="kwrd">byte</span>[1024];
    <span class="kwrd">int</span> bytesRead;
    <span class="kwrd">do</span>
    {
        bytesRead = responseStream.Read(buffer, 0, buffer.Length);                    
        memoryStream.Write(buffer, 0, bytesRead);
    } while (bytesRead &gt; 0);

    file.Data = memoryStream.ToArray();
}            </pre>
</div>
<p>And the only thing that remains is to return our FileSystemInfo instance.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">return</span> file;</pre>
</div>
<p>Voila, that&#8217;s the whole implementation of the DownloadFile(&#8230;) method.</p>
<p>Thanks to the fact that we did most of the work during the previous parts, this turned out to be a rather short article. Check out the Dropbox REST API documentation if you want to explore it further and implement new features on your own.</p>
<p><a href="https://www.dropbox.com/developers/reference/api" target="_blank">https://www.dropbox.com/developers/reference/api</a></p>
<p>In part 5 I&#8217;ll discuss how you can upload new files to your Dropbox account. You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/dropbox/'>Dropbox</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/3932/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/3932/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/3932/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3932&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/02/26/dropbox-rest-api-part-4-download-a-file/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/12/logo1.png" medium="image">
			<media:title type="html">DropBox Logo</media:title>
		</media:content>
	</item>
		<item>
		<title>Dropbox REST API Part 3: Create, Delete and Move Folders</title>
		<link>http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/</link>
		<comments>http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 13:33:26 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Dropbox API]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=3893</guid>
		<description><![CDATA[Introduction In the previous part (part 2: API Requests) I mentioned that the third part would show you how to perform various folder operations such as creating, deleting and moving folders. Well it has been a month, so let&#8217;s get to it. Go to the download page and download the source code of part 2 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3893&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><a href="http://cgeers.files.wordpress.com/2011/12/logo1.png"><img src="http://cgeers.files.wordpress.com/2011/12/logo1.png?w=480" alt="DropBox Logo" title="DropBox Logo"   class="alignright size-full wp-image-3688" /></a></p>
<p>In the previous part (<a href="http://cgeers.com/2012/01/08/dropbox-rest-api-part-2-api-requests/" target="_blank">part 2: API Requests</a>) I mentioned that the third part would show you how to perform various folder operations such as creating, deleting and moving folders.</p>
<p>Well it has been a month, so let&#8217;s get to it. Go to the download page and download the source code of part 2 (Article #63). Unzip and open the solution in Visual Studio. Make sure you modify the API key and secret located in the console application (Program.cs code file). Replace the values with your own application&#8217;s key and secret.</p>
<p>Ready? Set? OK, let&#8217;s start with creating folders&#8230;</p>
<p><span id="more-3893"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#create">Create Folder</a></li>
<li><a href="#encoding">URL Encoding</a></li>
<li><a href="#move">Move Folder</a></li>
<li><a href="#delete">Delete Folder</a></li>
</ul>
<p><a title="create" name="create"></a><strong>Create Folder</strong></p>
<p>The Dropbox REST API states that to <a href="http://www.dropbox.com/developers/reference/api#fileops-create-folder" target="_blank">create a folder</a> you must supply at least two parameters, namely:</p>
<ol>
<li><strong>root</strong>: The root relative to which the path is specified. Valid values are sandbox and dropbox.</li>
<li><strong>path</strong>: The path to the new folder to create relative to the root</li>
</ol>
<p>After creating the folder Dropbox returns some metadata about it. As usual this data is JSON-formatted. Let&#8217;s create a simple class decorated with attributes from the <a href="http://james.newtonking.com/projects/json-net.aspx" target="_blank">Json.NET library</a> so that we can easily deserialize this data.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[JsonObject(MemberSerialization.OptIn)]
<span class="kwrd">public</span> <span class="kwrd">class</span> FileSystemInfo
{
    [JsonProperty(PropertyName = <span class="str">"rev"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Revision { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"bytes"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">long</span> Bytes { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"modified"</span>)]
    <span class="kwrd">public</span> DateTime Modified { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"path"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Path { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    [JsonProperty(PropertyName = <span class="str">"root"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">string</span> Root { <span class="kwrd">get</span>; <span class="kwrd">internal</span> <span class="kwrd">set</span>; }

    <span class="rem">//...</span>
}</pre>
</div>
<p>The FileSystemInfo type is very similar to the File type shown in part 2 of this series. I&#8217;ve abbreviated the code here for readability. <a href="http://cgeers.com/download/">Download the source</a> and check it out if you want to see the whole class. This type will also be used as the return type of the Move(&#8230;) and Delete(&#8230;) methods that we&#8217;ll implement later.</p>
<p>Let&#8217;s expand the DropboxApi type so that we can create a folder in the following manner:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> folder = api.CreateFolder(<span class="str">"dropbox"</span>, <span class="str">"/test"</span>);</pre>
</div>
<p>First you need to specify the root. Valid values are sandbox or dropbox (production). Then you need to specify the folder relative to the root. Subdirectories are allowed.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> folder = api.CreateFolder(<span class="str">"dropbox"</span>, <span class="str">"/test/subdir"</span>);</pre>
</div>
<p>The implementation of the CreateFolder(&#8230;) method is similar to the API requests we handled in part 2.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> FileSystemInfo CreateFolder(<span class="kwrd">string</span> root, <span class="kwrd">string</span> path)
{
    <span class="kwrd">var</span> uri = <span class="kwrd">new</span> Uri(<span class="kwrd">new</span> Uri(DropboxRestApi.BaseUri),
        String.Format(<span class="str">"fileops/create_folder?root={0}&amp;path={1}"</span>, 
        root, UpperCaseUrlEncode(path)));
    <span class="kwrd">var</span> json = GetResponse(uri);
    <span class="kwrd">return</span> ParseJson&lt;FileSystemInfo&gt;(json);
}</pre>
</div>
<p>First we compose the URL to call, e.g.:</p>
<p><a href="https://api.dropbox.com/1/fileops/create_folder?root=dropbox&amp;path=%2Ftest" target="_blank">https://api.dropbox.com/1/fileops/create_folder?root=dropbox&amp;path=%2Ftest</a></p>
<p>Then we retrieve the response (JSON) by calling the GetResponse(&#8230;) method (see part 2), which signs the request using OAuth, and deserialize it into a Folder object using the Json.NET library.</p>
<p>You can examine the folder metadata afterwards:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> folder = api.CreateFolder(<span class="str">"dropbox"</span>, <span class="str">"/test"</span>);
Console.WriteLine(<span class="str">"Folder created."</span>);
Console.WriteLine(String.Format(<span class="str">"Root: {0}"</span>, folder.Root));
Console.WriteLine(String.Format(<span class="str">"Path: {0}"</span>, folder.Path));
Console.WriteLine(String.Format(<span class="str">"Modified: {0}"</span>, folder.Modified));     </pre>
</div>
<p>Which outputs:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/02/dropbox.png"><img src="http://cgeers.files.wordpress.com/2012/02/dropbox.png?w=480&h=140" alt="Create a Folder" title="Create a Folder" width="480" height="140" class="aligncenter size-full wp-image-3912" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="encoding" name="encoding"></a><strong>URL Encoding</strong></p>
<p>Did you notice that I URL encoded the path parameter in the CreateFolder(&#8230;) method? This is necessary in order to send the request. However there is a small issue that we must address.</p>
<p>Let&#8217;s say we use the <a href="http://msdn.microsoft.com/en-us/library/4fkewx0t.aspx" target="_blank">HttpUtility.UrlEncode</a>(&#8230;) method to URL encode the path.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">var</span> path = HttpUtility.UrlEncode(path);</pre>
</div>
<p>This will transform the path /test info %2ftest. The slash (/) is translated to %2f. However if you use that value with the Dropbox API you&#8217;ll get an error informing you that the signature is invalid. </p>
<p>Apparently the Dropbox API doesn&#8217;t like lowercased escaped paths. Instead of %2f it expects %2F (notifice the upper-casing!). Luckily StackOverflow provided an answer for this problem:</p>
<p><a href="http://stackoverflow.com/questions/918019/net-urlencode-lowercase-problem" target="_blank">http://stackoverflow.com/questions/918019/net-urlencode-lowercase-problem</a></p>
<p>So that&#8217;s why I&#8217;ve included the (private) UpperCaseUrlEncode(&#8230;) method to the DropboxApi type. This method encodes the path and makes sure the escaped parts are correctly cased.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">string</span> UpperCaseUrlEncode(<span class="kwrd">string</span> s)
{
    <span class="kwrd">char</span>[] temp = HttpUtility.UrlEncode(s).ToCharArray();
    <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; temp.Length - 2; i++)
    {
        <span class="kwrd">if</span> (temp[i] == <span class="str">'%'</span>)
        {
            temp[i + 1] = <span class="kwrd">char</span>.ToUpper(temp[i + 1]);
            temp[i + 2] = <span class="kwrd">char</span>.ToUpper(temp[i + 2]);
        }
    }
    <span class="kwrd">return</span> <span class="kwrd">new</span> <span class="kwrd">string</span>(temp);
}</pre>
</div>
<p><a href="#top">Top of page</a></p>
<p><a title="move" name="move"></a><strong>Move Folder</strong></p>
<p>You&#8217;ve already done most of the work by now. We can reuse most of the code to move a folder (or file).</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
folder = api.Move(<span class="str">"dropbox"</span>, <span class="str">"/test"</span>, <span class="str">"/temp"</span>);</pre>
</div>
<p>Apart from the URL the implementation is the same as the CreateFolder(&#8230;) method.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> FileSystemInfo Move(<span class="kwrd">string</span> root, <span class="kwrd">string</span> fromPath, <span class="kwrd">string</span> toPath)
{
    <span class="kwrd">var</span> uri = <span class="kwrd">new</span> Uri(<span class="kwrd">new</span> Uri(DropboxRestApi.BaseUri),
        String.Format(<span class="str">"fileops/move?root={0}&amp;from_path={1}&amp;to_path={2}"</span>,
        root, UpperCaseUrlEncode(fromPath), UpperCaseUrlEncode(toPath)));
    <span class="kwrd">var</span> json = GetResponse(uri);
    <span class="kwrd">return</span> ParseJson&lt;FileSystemInfo&gt;(json);
}</pre>
</div>
<p>The Move(&#8230;) method 3 parameters, namely:</p>
<ol>
<li><strong>root</strong>: The root. Valid values are sandbox or dropbox.</li>
<li><strong>fromPath</strong>: The file or folder to be copied from relative to the root.</li>
<li><strong>toPath</strong>: The destination path, including the new name for the file or folder, relative to root.</li>
</ol>
<p><a href="#top">Top of page</a></p>
<p><a title="delete" name="delete"></a><strong>Delete Folder</strong></p>
<p>Let&#8217;s clean up after ourselves and delete the folder(s) we created. First we created a folder named &#8220;test&#8221;, then moved it to &#8220;temp&#8221;. So let&#8217;s delete that one.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
folder = api.Delete(<span class="str">"dropbox"</span>, <span class="str">"/temp"</span>);</pre>
</div>
<p>Again the implementation of the Delete(&#8230;) method is very similar to the CreateFolder(&#8230;) and Move(&#8230;) methods.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">public</span> FileSystemInfo Delete(<span class="kwrd">string</span> root, <span class="kwrd">string</span> path)
{
    <span class="kwrd">var</span> uri = <span class="kwrd">new</span> Uri(<span class="kwrd">new</span> Uri(DropboxRestApi.BaseUri),
        String.Format(<span class="str">"fileops/delete?root={0}&amp;path={1}"</span>, 
        root, UpperCaseUrlEncode(path)));
    <span class="kwrd">var</span> json = GetResponse(uri);
    <span class="kwrd">return</span> ParseJson&lt;FileSystemInfo&gt;(json);
}      </pre>
</div>
<p>And that is all there is to it! Apart from an issue with the casing of the URL encoding creating, moving and deleting folders is pretty easy with the Dropbox REST API. Note that you can also use the Move(&#8230;) and Delete(&#8230;) methods with files, not just folders.</p>
<p>For the sake of completeness, here&#8217;s the entire flow of the client application.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="rem">// Create a folder</span>
<span class="kwrd">var</span> folder = api.CreateFolder(<span class="str">"dropbox"</span>, <span class="str">"/test"</span>);
Console.WriteLine(<span class="str">"Folder created."</span>);
Console.WriteLine(String.Format(<span class="str">"Root: {0}"</span>, folder.Root));
Console.WriteLine(String.Format(<span class="str">"Path: {0}"</span>, folder.Path));
Console.WriteLine(String.Format(<span class="str">"Modified: {0}"</span>, folder.Modified));                                    

<span class="rem">// Move a folder</span>
folder = api.Move(<span class="str">"dropbox"</span>, <span class="str">"/test"</span>, <span class="str">"/temp"</span>);

<span class="rem">// Delete a folder</span>
folder = api.Delete(<span class="str">"dropbox"</span>, <span class="str">"/temp"</span>);</pre>
</div>
<p>Check out the Dropbox REST API documentation if you want to explore it further.</p>
<p><a href="https://www.dropbox.com/developers/reference/api" target="_blank">https://www.dropbox.com/developers/reference/api</a></p>
<p>You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/dropbox/'>Dropbox</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/3893/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/3893/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/3893/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3893&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/02/19/dropbox-rest-api-part-3-create-delete-and-move-folders/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2011/12/logo1.png" medium="image">
			<media:title type="html">DropBox Logo</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/02/dropbox.png" medium="image">
			<media:title type="html">Create a Folder</media:title>
		</media:content>
	</item>
		<item>
		<title>Enabling SSL for a WCF Service</title>
		<link>http://cgeers.com/2012/01/30/enabling-ssl-for-a-wcf-service/</link>
		<comments>http://cgeers.com/2012/01/30/enabling-ssl-for-a-wcf-service/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 14:21:03 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://cgeers.com/?p=3817</guid>
		<description><![CDATA[Introduction Last week a reader mailed me with some questions about my &#8220;WCF over HTTPS&#8221; blog post, which I wrote almost 3 years ago. I created some sample code to help him enable SSL for a WCF service. Last year this was my most popular article, so I thought it would make sense to create [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3817&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a title="introduction" name="introduction"></a><strong>Introduction</strong><img class="alignnone size-medium wp-image-24 alignright" style="float:right;" src="http://cgeers.files.wordpress.com/2008/04/dotnetwcf.gif?w=80&h=80" alt="" width="80" height="80" /></p>
<p>Last week a reader mailed me with some questions about my &#8220;<a href="http://cgeers.com/2009/08/07/wcf-over-https/" target="_blank">WCF over HTTPS</a>&#8221; blog post, which I wrote almost 3 years ago.</p>
<p>I created some sample code to help him enable SSL for a WCF service. Last year this was my most popular article, so I thought it would make sense to create a new up-to-date version that shows you step-by-step how to enable SSL for a WCF service with as little fuss as possible.</p>
<p>Let&#8217;s get started&#8230;</p>
<p><span id="more-3817"></span></p>
<p><a title="top" name="top"></a><strong>Table Of Contents</strong></p>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#theservice">Step 1 &#8211; The Service</a></li>
<li><a href="#configuration">Step 2 &#8211; Configuration</a></li>
<li><a href="#hosting">Step 3 &#8211; Hosting The Service</a></li>
<li><a href="#certificate">Step 4 &#8211; SSL Certificate</a></li>
<li><a href="#enablessl">Step 5 &#8211; Enable SSL</a></li>
<li><a href="#consume">Step 6 &#8211; Consume The Service</a></li>
</ul>
<p><a title="theservice" name="theservice"></a><strong>Step 1 &#8211; The Service</strong></p>
<p>First we are going to create a simple and easy-to-use WCF service. Start up Visual Studio 2010 and create a new blank solution called &#8220;SslEnabledWcfService&#8221;. Next add a new class library project to it called &#8220;CustomerService&#8221;. </p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf1.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf1.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-3825" /></a></p>
<p>Add a reference to the System.ServiceModel and System.Runtime.Serialization assemblies to the CustomerService project.</p>
<p>Add a new interface called ICustomerService to the project<br />
 that defines the service contract.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[ServiceContract]
<span class="kwrd">public</span> <span class="kwrd">interface</span> ICustomerService
{
    [OperationContract]
    IEnumerable&lt;Customer&gt; GetCustomers();
}</pre>
</div>
<p>The service returns a collection of customers. Each customer is represented by an instance of the Customer class. </p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[DataContract]
<span class="kwrd">public</span> <span class="kwrd">class</span> Customer
{
    [DataMember]
    <span class="kwrd">public</span> Guid Id { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [DataMember]
    <span class="kwrd">public</span> <span class="kwrd">string</span> FirstName { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }

    [DataMember]
    <span class="kwrd">public</span> <span class="kwrd">string</span> LastName { <span class="kwrd">get</span>; <span class="kwrd">set</span>; }
}</pre>
</div>
<p>Go ahead and add a file called Customer.cs. Copy and paste the code listed above.</p>
<p>The actual service implementation is very simple. It returns a list of customers which I create on the fly. No use in dealing with a database, or another persistant data store for this post. Let&#8217;s keep things as simple as possible.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
[ServiceBehavior]
<span class="kwrd">public</span> <span class="kwrd">class</span> CustomerService : ICustomerService
{
    <span class="kwrd">private</span> IEnumerable&lt;Customer&gt; LoadCustomers()
    {
        <span class="rem">//...</span>
    }

    <span class="kwrd">public</span> IEnumerable&lt;Customer&gt; GetCustomers()
    {
        <span class="kwrd">var</span> customers = <span class="kwrd">new</span> List&lt;Customer&gt;();
        customers.AddRange(LoadCustomers());
        <span class="kwrd">return</span> customers;
    }
}</pre>
</div>
<p>Check out the source code accompanying this post for the full code of the CustomerService class.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="configuration" name="configuration"></a><strong>Step 2 &#8211; Configuration</strong></p>
<p>OK, now it&#8217;s time to add some configuration for our service. The host process (IIS) needs this to be able to figure out how to host the service. First add a new application configuration file called Web.config to the CustomerService project.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf2.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf2.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-3835" /></a></p>
<p>First you need to list the service in the <a href="http://msdn.microsoft.com/en-us/library/ms731354.aspx" target="_blank">&lt;system.serviceModel&gt;</a> node.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">&lt;</span><span class="html">system.serviceModel</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">services</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">service</span> <span class="attr">name</span><span class="kwrd">="CustomerService.CustomerService"</span> 
              <span class="attr">behaviorConfiguration</span><span class="kwrd">="MyServiceBehavior"</span><span class="kwrd">&gt;</span>
        
      <span class="kwrd">&lt;</span><span class="html">endpoint</span> <span class="attr">address</span><span class="kwrd">=""</span> 
                <span class="attr">binding</span><span class="kwrd">="basicHttpBinding"</span>
                <span class="attr">bindingConfiguration</span><span class="kwrd">="TransportSecurity"</span> 
                <span class="attr">contract</span><span class="kwrd">="CustomerService.ICustomerService"</span> <span class="kwrd">/&gt;</span>
        
      <span class="kwrd">&lt;</span><span class="html">endpoint</span> <span class="attr">address</span><span class="kwrd">="mex"</span>
                <span class="attr">binding</span><span class="kwrd">="mexHttpsBinding"</span>
                <span class="attr">contract</span><span class="kwrd">="IMetadataExchange"</span> <span class="kwrd">/&gt;</span>      
    <span class="kwrd">&lt;/</span><span class="html">service</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">services</span><span class="kwrd">&gt;</span>
    
  <span class="rem">&lt;!--...--&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">system.serviceModel</span><span class="kwrd">&gt;</span></pre>
</div>
<p>As you can see the service is linked to a custom service behavior called &#8220;MyServiceBehavior&#8221;. You need to define this behavior in the <a href="http://msdn.microsoft.com/en-us/library/ms731298.aspx" target="_blank">&lt;behaviors&gt;</a> node of the &lt;system.serviceModel&gt; node.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">&lt;</span><span class="html">behaviors</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">serviceBehaviors</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">behavior</span> <span class="attr">name</span><span class="kwrd">="MyServiceBehavior"</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">serviceMetadata</span> <span class="attr">httpsGetEnabled</span><span class="kwrd">="true"</span> <span class="attr">httpsGetUrl</span><span class="kwrd">=""</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">serviceDebug</span> <span class="attr">includeExceptionDetailInFaults</span><span class="kwrd">="false"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">behavior</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">serviceBehaviors</span><span class="kwrd">&gt;</span>      
<span class="kwrd">&lt;/</span><span class="html">behaviors</span><span class="kwrd">&gt;</span></pre>
</div>
<p>Note that the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.description.servicemetadatabehavior.httpsgetenabled.aspx" target="_blank">httpsGetEnabled</a> property of the behavior is set to true. This allows us to retrieve metadata for the service using an HTTPS/GET request. Handy for creating our client proxies later on.</p>
<p>The first endpoint (non-mex) of the service is also tied to a custom binding (basicHttpBinding) called TransportSecurity.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">&lt;</span><span class="html">bindings</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">basicHttpBinding</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">binding</span> <span class="attr">name</span><span class="kwrd">="TransportSecurity"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">security</span> <span class="attr">mode</span><span class="kwrd">="Transport"</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">transport</span> <span class="attr">clientCredentialType</span><span class="kwrd">="None"</span> <span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">security</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">binding</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">basicHttpBinding</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">bindings</span><span class="kwrd">&gt;</span>          </pre>
</div>
<p>It is on the binding level that you must specify which security model the service uses. Here we set the mode to Transport (SSL) and turn off any type of <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.httptransportsecurity.clientcredentialtype.aspx" target="_blank">client authentication</a>.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="hosting" name="hosting"></a><strong>Step 3 &#8211; Hosting The Service</strong></p>
<p>The service has been created and configured. Time to host it. I&#8217;m using IIS 7.5 (7.5.7600.16385) on Windows 7 for this purpose. Create a new text file called &#8220;Service.svc&#8221;. Note the .svc extension! </p>
<p>Add it to the CustomerService project. </p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf3.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf3.png?w=480" alt="Solution Explorer" title="Solution Explorer"   class="aligncenter size-full wp-image-3846" /></a></p>
<p>It only contains one line, namely:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
&lt;%@ ServiceHost Language=<span class="str">"C#"</span>
                Service=<span class="str">"CustomerService.CustomerService"</span> 
                CodeBehind=<span class="str">"CustomerService.cs"</span> %&gt;</pre>
</div>
<p>Here you identify the service, the language used and the location of the code behind file. </p>
<p>Open up Windows Explorer and navigate to the default installation folder for IIS (C:\inetpub). I started with a clean installation to make things easy. Since I don&#8217;t host any other sites locally I deleted everything I found within the wwwroot subfolder. You might want to create a subfolder within the wwwroot folder to host your service. Once you have done so create a new directory called bin within the wwwroot folder or your custom subfolder.</p>
<p>To host the service you must copy the following files to the directory in which you host your service:</p>
<ul>
<li>Service.svc</li>
<li>Web.config</li>
<li>CustomerService.dll (\bin)</li>
</ul>
<p>You must copy the compiled CustomerService.dll assembly (and any other dependent assemblies) inside the bin folder! Just set your solution configuration to Release, rebuild your solution and copy the necessary files as described.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf4.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf4.png?w=480&h=87" alt="Inetpub wwwroot" title="Inetpub wwwroot" width="480" height="87" class="aligncenter size-full wp-image-3852" /></a></p>
<p>Almost there, we just need to configure IIS. Start up the Internet Information Services (IIS) Manager and navigate to the Default Web Site node in the left pane.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf5.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf5.png?w=480" alt="IIS Manager" title="IIS Manager"   class="aligncenter size-full wp-image-3854" /></a></p>
<p>Double click on the Default Document displayed in the middle pane under the IIS group.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf6.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf6.png?w=480" alt="Default Document" title="Default Document"   class="aligncenter size-full wp-image-3856" /></a></p>
<p>Remove all the documents listed there and afterwards add a new document called Service.svc. When we navigate to http://localhost we want IIS to serve up the Service.svc document by default.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf7.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf7.png?w=480&h=128" alt="Default Document" title="Default Document" width="480" height="128" class="aligncenter size-full wp-image-3857" /></a></p>
<p>Open your favorite browser (*cough* Chrome * cough*) and navigate to <a href="http://localhost" target="_blank">http://localhost</a>. You&#8217;ll be greeted by the following error page:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf8.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf8.png?w=480&h=361" alt="Secured Page" title="Secured Page" width="480" height="361" class="aligncenter size-full wp-image-3861" /></a></p>
<p>The page is secured and cannot be accessed via http. Exactly what we want! You can try and access it via <a href="https://localhost" target="_blank">https://localhost</a>, but this will result in a page not found error as we have not yet configured SSL.</p>
<p><a href="#top">Top of page</a></p>
<p><a title="certificate" name="certificate"></a><strong>Step 4 &#8211; SSL Certificate</strong></p>
<p>Before you can configure your service to use SSL you need a valid SSL certificate. Luckily you can create one yourself for development / testing purposes instead of purchasing one. Using the <a href="http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.80).aspx" target="_blank">makecert.exe</a> command-line utility you can create your own certificates. </p>
<p>Let&#8217;s quickly create a certificate. Start up an elevated Visual Studio Command Prompt and enter the following command:</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
makecert -r -pe -n “CN=YourComputerName” -b 01/01/2012 -e 01/01/2020
-eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp
“Microsoft RSA SChannel Cryptographic Provider” -sy 12</pre>
</div>
<p>Make sure to replace the term &#8220;YourComputerName&#8221; with your actual computer&#8217;s name. After executing the command you should get a simple &#8220;succeeded&#8221; message.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf9.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf9.png?w=480&h=148" alt="Makecert.exe" title="Makecert.exe" width="480" height="148" class="aligncenter size-full wp-image-3867" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="enablessl" name="enablessl"></a><strong>Step 5 &#8211; Enable SSL</strong></p>
<p>Alright, we have our SSL certificate. Let&#8217;s bind it to our service. Go back to IIS Manager and select the Default Web Site node. In the right pane click on the &#8220;Bindings&#8230;&#8221; link.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf10.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf10.png?w=480" alt="Bindings" title="Bindings"   class="aligncenter size-full wp-image-3870" /></a></p>
<p>In the Site Bindings popup click on the Add button to add a new binding.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf11.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf11.png?w=480&h=224" alt="Site Bindings" title="Site Bindings" width="480" height="224" class="aligncenter size-full wp-image-3872" /></a></p>
<p>and enter the following data to enable SSL for your site:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf12.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf12.png?w=480&h=261" alt="Site Binding" title="Site Binding" width="480" height="261" class="aligncenter size-full wp-image-3873" /></a></p>
<p>Be sure to select the SSL certificate you created earlier! Just click OK to add the binding and close the Site Bindings popup afterwards.</p>
<p>Restart your web site and navigate to <a href="https://localhost" target="_blank">https://localhost</a>. This time it&#8217;ll work, but you&#8217;ll probably get a warning message because of your untrusted SSL certificate. Just ignore it.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/wcf13.png"><img src="http://cgeers.files.wordpress.com/2012/01/wcf13.png?w=480&h=387" alt="SSL Enabled Service" title="SSL Enabled Service" width="480" height="387" class="aligncenter size-full wp-image-3875" /></a></p>
<p><a href="#top">Top of page</a></p>
<p><a title="consume" name="consume"></a><strong>Step 6 &#8211; Consume The Service</strong></p>
<p>Now that we have our service running in IIS and secured with SSL let&#8217;s test it. Time to consume the service. Add a new console application to the solution called ClientApp. Add a service reference to our newly created WCF service.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/service-reference.png"><img src="http://cgeers.files.wordpress.com/2012/01/service-reference.png?w=480&h=387" alt="Add Service Reference" title="Add Service Reference" width="480" height="387" class="aligncenter size-full wp-image-3877" /></a></p>
<p>When adding the service reference Visual Studio will report a problem with the SSL certificate.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/certificate-problem.png"><img src="http://cgeers.files.wordpress.com/2012/01/certificate-problem.png?w=480&h=375" alt="Certificate Problem" title="Certificate Problem" width="480" height="375" class="aligncenter size-full wp-image-3878" /></a></p>
<p>Just click Yes to proceed. The message is shown because the certificate has not been issued by a company you have chosen to trust.</p>
<p>After you&#8217;ve created the service reference you can consume the service. Let&#8217;s display a list of the customers.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">using</span> (<span class="kwrd">var</span> proxy = <span class="kwrd">new</span> CustomerServiceClient())
{
    <span class="kwrd">var</span> customers = proxy.GetCustomers();
    <span class="kwrd">foreach</span>(<span class="kwrd">var</span> customer <span class="kwrd">in</span> customers)
    {
        Console.WriteLine(String.Format(<span class="str">"{0} {1}"</span>, customer.FirstName, customer.LastName));
    }
}</pre>
</div>
<p>When you try to execute this code you&#8217;ll get the following exception:</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/securitynegotiatianexception1.png"><img src="http://cgeers.files.wordpress.com/2012/01/securitynegotiatianexception1.png?w=480&h=219" alt="SecurityNegotiatianException" title="SecurityNegotiatianException" width="480" height="219" class="aligncenter size-full wp-image-3883" /></a></p>
<p>The client application does not trust the service. You can fix this by inspecting the certificate which the service hands over to the client. You need to hook up a handler for the <a href="http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx" target="_blank">ServicePointManager&#8217;s ServerCertifcateValidationCallback</a>.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
ServicePointManager.ServerCertificateValidationCallback += customXertificateValidation;</pre>
</div>
<p>When this callback is triggered you can inspect the server certificate.</p>
<div class="csharpcode">
<!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre>
<span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> customXertificateValidation(<span class="kwrd">object</span> sender, X509Certificate cert,
    X509Chain chain, SslPolicyErrors error)
{
    <span class="kwrd">var</span> certificate = (X509Certificate2) cert;

    <span class="rem">// Inspect the server certficiate here to validate </span>
    <span class="rem">// that you are dealing with the correct server.</span>
    <span class="rem">// If so return true, if not return false.</span>
    <span class="kwrd">return</span> <span class="kwrd">true</span>;
}</pre>
</div>
<p>We&#8217;re finally there. If you run the client application now it will correctly list the customers returned by the SSL-enabled WCF service.</p>
<p><a href="http://cgeers.files.wordpress.com/2012/01/output1.png"><img src="http://cgeers.files.wordpress.com/2012/01/output1.png?w=480&h=106" alt="The Customers" title="The Customers" width="480" height="106" class="aligncenter size-full wp-image-3887" /></a></p>
<p>You can download the source code accompanying this article from the <a href="http://cgeers.com/download/" target="_blank">download page</a>. If you have any questions or suggestions please drop me an e-mail or submit a comment.</p>
<p><a href="#top">Top of page</a></p>
<br />Filed under: <a href='http://cgeers.com/category/programming/c/'>C#</a>, <a href='http://cgeers.com/category/programming/iis/'>IIS</a>, <a href='http://cgeers.com/category/programming/'>Programming</a>, <a href='http://cgeers.com/category/programming/wcf/'>WCF</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cgeers.wordpress.com/3817/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cgeers.wordpress.com/3817/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cgeers.wordpress.com/3817/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cgeers.com&#038;blog=2504479&#038;post=3817&#038;subd=cgeers&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cgeers.com/2012/01/30/enabling-ssl-for-a-wcf-service/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fb4348981494310223376b6e6e094e0b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cgeers</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2008/04/dotnetwcf.gif" medium="image" />

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf1.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf2.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf3.png" medium="image">
			<media:title type="html">Solution Explorer</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf4.png" medium="image">
			<media:title type="html">Inetpub wwwroot</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf5.png" medium="image">
			<media:title type="html">IIS Manager</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf6.png" medium="image">
			<media:title type="html">Default Document</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf7.png" medium="image">
			<media:title type="html">Default Document</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf8.png" medium="image">
			<media:title type="html">Secured Page</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf9.png" medium="image">
			<media:title type="html">Makecert.exe</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf10.png" medium="image">
			<media:title type="html">Bindings</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf11.png" medium="image">
			<media:title type="html">Site Bindings</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf12.png" medium="image">
			<media:title type="html">Site Binding</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/wcf13.png" medium="image">
			<media:title type="html">SSL Enabled Service</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/service-reference.png" medium="image">
			<media:title type="html">Add Service Reference</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/certificate-problem.png" medium="image">
			<media:title type="html">Certificate Problem</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/securitynegotiatianexception1.png" medium="image">
			<media:title type="html">SecurityNegotiatianException</media:title>
		</media:content>

		<media:content url="http://cgeers.files.wordpress.com/2012/01/output1.png" medium="image">
			<media:title type="html">The Customers</media:title>
		</media:content>
	</item>
	</channel>
</rss>
