2012年11月14日 星期三

Skydrive REST API for Windows desktop app (2)

Previous article was presented how to use REST API for user log-on and authentication. In the next, we want to know how to retrieve file system information on Skydrive and how to upload files to it.

Step 3: retrieve file system information from Skydrive

API supported GET method for retrieving data
GET https://apis.live.net/v5.0/me/skydrive/files?access_token=ACCESS_TOKEN
We also can set filter on fragment for getting folders, albums, audio, photos or videos.
GET https://apis.live.net/v5.0/me/skydrive/files?filter=folders&access_token=ACCESS_TOKEN


After sending request to Live Connect REST API, it returns json struct for scripting the file system information on your Skydrive, it looks like
{ "data": [
        {
            "id": "photo.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!131", 
            "upload_location": "https://apis.live.net/v5.0/photo.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!110/files/", 
            ...
            "type": "folder",
            ...
        }, {
            "id": "file.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!119", 
            ...             
            "upload_location": "https://apis.live.net/v5.0/file.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!119/content/", 
            ...
            "type": "file", 
            ...
        }
    ] }

There is a important thing that the REST API returns json characters were encoded by Normal ASCII(code 1252). But in the .Net framework environment, the default decoder for String builder is using Unicode, so we need to convert code page for retrieved json characters.


It can be used both WebClient or HttpWebRequest classes to implement the http request in .Net framework. following is a sample code using WebClient to retrieve all folders on Skydrive root.

 private void getSkyDriveAccess()  
 {  
   if (App.Current.Properties.Contains("oauthData"))  
     makeRequest(@"https://apis.live.net/v5.0/me/skydrive/files?filter=folders&" + App.Current.Properties["access_token"]);  
 }  
 private void makeRequest(string requestUrl)  
 {  
   WebClient wc = new WebClient();  
   wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);  
   wc.DownloadStringAsync(new Uri(requestUrl));  
 }  
 void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)  
 {  
   IDictionary<string , object> data = deserObjJson(e.Result);  
   ArrayList dataitems = (ArrayList)data["data" ];  
   string upload_location = "";  
   foreach ( object datajson in dataitems)  
   {  
     IDictionary<string , object > item = datajson as IDictionary< string, object>;  
     string id = item[ "id"].ToString();  
     string name = Encoding.UTF8.GetString(Encoding.GetEncoding(1252).GetBytes(item["name"].ToString()));  
     if (name.ToLower().Equals("testfolder"))  
     {  
       upload_location = item["upload_location"].ToString();  
     }  
   }  
 }  


Step 4: uploading files

Before starting access folders and files on Skydrive, the article of reference about Folders and files operating would be help us knowing how to use API methods and formats to access them.

There are two methods for uploading files, one is PUT method
PUT https://apis.live.net/v5.0/me/skydrive/files/HelloWorld.txt?access_token=ACCESS_TOKEN

Hello, World!
And another is POST method
POST https://apis.live.net/v5.0me/skydrive/files?access_token=ACCESS_TOKEN
Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="file"; filename="MyNewFile.txt"
Content-Type: text/plain

These are the contents of my new file.
--AaB03x--

After finishing method process, API will return the uploaded file information on Skydrive.
Following is a sample code using HttpWebRequest class to implement uploading function.
 private void UploadFileByPutMethod(string fileName)  
 {  
   string uri = @"https://apis.live.net/v5.0/me/skydrive/files/" + fileName + "?" + App.Current.Properties["access_token"];  
   HttpWebRequest req = WebRequest .CreateHttp(uri);  
   req.Method = "PUT";  
   using (Stream reqStream = req.GetRequestStream())  
   {  
     byte[] buff = Encoding.UTF8.GetBytes("Hello, SkyDrive!加上中文");  
     reqStream.Write(buff, 0, buff.Length);  
   }  
   string resJson = "";  
   using (WebResponse res = req.GetResponse())  
   {  
     StreamReader sr = new StreamReader(res.GetResponseStream());  
     resJson = sr.ReadToEnd();  
   }  
   MessageBox.Show(resJson);  
 }  
 private void UploadFileByPostMethod(string uploadLocation, string filePath, string mimeType)  
 {  
   string uri = uploadLocation + "?" + App.Current.Properties["access_token"];  
   HttpWebRequest req = WebRequest.CreateHttp(uri);  
   req.Method = "POST";  
   req.ContentType = "multipart/form-data; boundary=AaB03x" ;  
   string requestHeader =  
     "--AaB03x" + Environment.NewLine +  
     "Content-Disposition: form-data; name=\"file\"; filename=\"" + System.IO.Path.GetFileName(filePath) + "\"" + Environment.NewLine +  
     "Content-Type: " + mimeType + Environment.NewLine + Environment.NewLine;  
   string requestTrailer =  
     "--AaB03x--";  
   byte[] buffHeader = Encoding.UTF8.GetBytes(requestHeader);  
   byte[] buffTrailer = Encoding.UTF8.GetBytes(requestTrailer);  
   byte[] buffFile = null;  
   using (BinaryReader br = new BinaryReader(File .OpenRead(filePath)))  
   {  
     buffFile = br.ReadBytes((int)br.BaseStream.Length);  
   }  
   req.ContentLength = buffHeader.Length + buffTrailer.Length + buffFile.Length;  
   using (Stream reqStream = req.GetRequestStream())  
   {  
     reqStream.Write(buffHeader, 0, buffHeader.Length);  
     reqStream.Write(buffFile, 0, buffFile.Length);  
     reqStream.Write(buffTrailer, 0, buffTrailer.Length);  
   }  
   string resJson = "";  
   using (WebResponse res = req.GetResponse())  
   {  
     StreamReader sr = new StreamReader(res.GetResponseStream());  
     resJson = sr.ReadToEnd();  
   }  
   MessageBox.Show(resJson);  
 }  

Because this project was cancelled, I have to stop study forward in this topic. The planning next step is multiple uploading or scripting of specified data format, likes photos, albums and etc.
But maybe I can post article talking something about the REST architecture when I have time. :P


2012年11月8日 星期四

SkyDrive REST API for Windows desktop app (1)

I researched for a week to figure out that has there any source code or samples for this issue. But it seems like difficult build-on the desktop apps, and very difference with previous version of Live SDK. Finally, I found and followed the Getting Start of REST API in Microsoft Live Connect Center to build my desktop application.


Step 1: Create and manage application on Live Connect Center

In first, you must sign-on the manager page of Live Connect Center, then create and manage your applications.

Fill out all of required information, it shows the Client ID for your client-side application.

Then now, we can start to write client-side application for using SkyDrive REST API.


Step 2: Implement client-side authentication

Difference with the guideline of user signing, I would like to use access token for client-side authentication, so there is a little change that I set the response_type=token .
Following is the request URL of Live Connect Oauth 2.0

https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=SCOPE_STRING&response_type=token&redirect_uri=https://login.live.com/oauth20_desktop.srf

CLIENT_ID : the client id of managed application on Live Connect Center
SCOPE_STRING : permissions which gets from the user to access their info on app, see also guideline of scopes and permissions.

After user agree the consent, Oauth 2.0 API will return a URL that contains token and expired time, looks like

https://login.live.com/oauth20_desktop.srf?lc=1033#access_token=AsDfGhJkL1234&token_type=bearer&expires_in=3600&scope=wl.signin%20wl.skydrive

The access_token would be found in the URL fragment if user sign-in and authorized successfully.

Here is a sample code which I implement the authentication by using WebBrowser class in C#
 private static string scope = "wl.signin%20wl.skydrive%20wl.skydrive_update";  
 private const string client_id = "0000000000012345";  
 private static Uri signInUrl = new Uri(String .Format(@"https://login.live.com/oauth20_authorize.srf?client_id={0}&scope={1}&response_type=token&redirect_uri=https://login.live.com/oauth20_desktop.srf", client_id, scope));  
 webBrowser.Navigate(signInUrl);  
 webBrowser.LoadCompleted += webBrowser_LoadCompleted;  
 private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)  
 {  
   if (e.Uri.Fragment.Contains("access_token"))  
   {  
     if (App.Current.Properties.Contains("oauthData"))  
       App.Current.Properties.Clear();  
     App.Current.Properties.Add("oauthData", 1);  
     string[] responseOauth = Regex.Split(e.Uri.Fragment.Remove(0, 1), "&");  
     for (int i = 0; i < responseOauth.Count(); i++)  
     {  
       string[] nvPair = Regex.Split(responseOauth[i], "=");  
       App.Current.Properties.Add(nvPair[0], responseOauth[i]);  
     }  
     this.Close();  
   }  
 }  

#file retrieving and uploading will be continued in the next article

2012年11月5日 星期一

Source Code Formatter

Depends on the future days, I would like to use the code block for presentation of sample codes. There're some sites of source code formatter for writing blog's article. I wish it would be helpful.

http://codeformatter.blogspot.tw/
many options, especially alternative background for code lines.

http://formatmysourcecode.blogspot.tw/
simply source code formatter

test

test123