none
Using REST API to access Azure Tables from Windows Phone.

    Question

  • Hi all,
    As a part of my Windows Phone Application I have to access azure tables from Windows Phone using REST API.
    But when making a request to azure tables I am getting  NULL as a response. I am not able to debug what is problem with my code.
    I call GetEntity Function every time I have to access azure tables. You can check for GetEntity function in the attached file.
    I am attaching my code with this mail.
     
    If anybody can help me regarding this problem kindly let me know ASAP
     

    CODE

    private void GetEntity(String tableName, String partitionKey, String rowKey)
            {
                String requestMethod = "GET";

                String urlPath = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')", tableName, partitionKey, rowKey);



                String dateInRfc1123Format = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);

                String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
                String stringToSign = String.Format(
                      "{0}\n\n\n{1}\n{2}",
                      requestMethod,
                      dateInRfc1123Format,
                      canonicalizedResource);
                String authorizationHeader = CreateAuthorizationHeader(stringToSign);
                HttpWebResponse response;
                Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
            
               
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers[HttpRequestHeader.ProxyAuthorization] = null;
                request.Headers["Address"] = uri.ToString();
                request.Headers["Method"] = requestMethod;
                request.Headers["x-ms-date"]= DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
                request.Headers["x-ms-version"]= "2011-08-18";            
                request.Headers["Authorization"] = authorizationHeader;
                request.Headers["Accept-Charset"] = "UTF-8";
                request.Headers["ContentType"] = "application/atom+xml,application/xml";
                request.ContentType = "application/atom+xml,application/xml";
                request.Headers["DataServiceVersion"] = "1.0;NetFx";
                request.Headers["MaxDataServiceVersion"] = "1.0;NetFx";
                
               
                
               using (response = GetResponse(request))
                {
                    Stream dataStream = response.GetResponseStream();
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        String responseFromServer = reader.ReadToEnd();
                    }
                }
            }


    ///////////////////////////////
            public HttpWebResponse GetResponse(HttpWebRequest request)
            {
                var dataReady = new AutoResetEvent(false);
                HttpWebResponse response = null;
                var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
                {
                    response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                    dataReady.Set();
                });

                request.BeginGetResponse(callback, request);
                    return response;
            }
    /////////////////////
     private String CreateAuthorizationHeader(String canonicalizedString)
     {
         String signature = string.Empty;
         using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key)))
               
         {
             Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
             signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
         }
     
        String authorizationHeader = String.Format(
               CultureInfo.InvariantCulture,
               "{0} {1}:{2}",
               AzureStorageConstants.SharedKeyAuthorizationScheme,
               AzureStorageConstants.Account,
               signature);
     
        return authorizationHeader;
     }




    //////////////////
    public static class AzureStorageConstants
            {
            

             private static String TableAccount = "datablobs";
             private static String cloudEndPointFormat = "http://" + TableAccount + ".table.core.windows.net/";
           

            private static String cloudKey = "Primary Access Key";// Here actual key is written.
            private static string AzureStorage_SharedKeyAuthorizationScheme = "SharedKey";
          

                public static String Account
                {
                    get { return TableAccount; }
                }

                public static string SharedKeyAuthorizationScheme
                {
                    get { return AzureStorage_SharedKeyAuthorizationScheme; }
                }

                public static string Key
                {
                    get { return  cloudKey; }
                }
                
                public static String TableEndPoint
                {
                    get { return cloudEndPointFormat; }
                }
            }

    Saturday, June 30, 2012 11:40 AM

Answers

  • Working code.The below mentioned code is completely working and Mr. Arwind  even i know what your are saying and i asked for answer to my question not some other way of doing it . Btw thank you

    private void GetEntity2(String tableName, String partitionKey, String rowKey)
            {
                String requestMethod = "GET";

                String urlPath = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')", tableName, partitionKey, rowKey);

                String storageServiceVersion = "2009-09-19";

                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
                String stringToSign = String.Format(
                      "{0}\n\n\n{1}\n{2}",
                      requestMethod,
                      dateInRfc1123Format,
                      canonicalizedResource);
                String authorizationHeader = CreateAuthorizationHeader(stringToSign);

                Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers["x-ms-date"] = dateInRfc1123Format;
                request.Headers["x-ms-version"] = storageServiceVersion;
                request.Headers["Authorization"] = authorizationHeader;
                request.Headers["Accept-Charset"] = "UTF-8";
                request.Accept = "application/atom+xml,application/xml";
                request.Headers["DataServiceVersion"] = "1.0;NetFx";
                request.Headers["MaxDataServiceVersion"] = "1.0;NetFx";
                GetResponse(request);
            }

        public void GetResponse(HttpWebRequest request)
            {
                var dataReady = new AutoResetEvent(false);
                HttpWebResponse response = null;
                var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
                {
                    try
                    {              
                        response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                        Stream dataStream = response.GetResponseStream();
                        using (StreamReader reader = new StreamReader(dataStream))
                        {
                            String responseFromServer = reader.ReadToEnd();
                            this.Dispatcher.BeginInvoke(delegate
                            {
                               MessageBox.Show(responseFromServer);

                            });
                        }
                    }
                    

                    dataReady.Set();
                });

                request.BeginGetResponse(callback, request);


            }




      private String CreateAuthorizationHeader(String canonicalizedString)
            {
                String signature = string.Empty;
                using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key)))
                {
                    Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
                    signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                }

                String authorizationHeader = String.Format(
                       CultureInfo.InvariantCulture,
                       "{0} {1}:{2}",
                       AzureStorageConstants.SharedKeyAuthorizationScheme,
                       AzureStorageConstants.Account,
                       signature);

                return authorizationHeader;
            }



    public static class AzureStorageConstants
            {

                private static String TableAccount = "account name";
                private static String cloudEndPointFormat = "http://" + StorageAccount + ".table.core.windows.net/";

                private static String cloudKey = "account key";
                private static string AzureStorage_SharedKeyAuthorizationScheme = "SharedKey";

                public static String Account
                {
                    get { return TableAccount; }
                }

                public static string SharedKeyAuthorizationScheme
                {
                    get { return AzureStorage_SharedKeyAuthorizationScheme; }
                }

                public static string Key
                {
                    get { return cloudKey; }
                }

                public static String TableEndPoint
                {
                    get { return cloudEndPointFormat; }
                }

            }

    • Marked as answer by twoface21 Sunday, July 15, 2012 2:20 PM
    Sunday, July 15, 2012 2:20 PM

All replies

  • I haven't gone through your code to see what's going on exactly but what I would suggest is using the managed wrapper Brad Adams has developed to access Windows Azure Storage without needing to go all the way down to running Rest calls to the API.

    You can use nugget to install the package you'll find by searching for Phone.Storage, or by manually downloading it from http://nuget.org/packages/Phone.Storage and you can see how you can use it from here http://mobile.dzone.com/articles/windows-azure-storage-client

    Let me know if that works for you or if there is a specific reason you need to go to the Rest Service.


    Kostas Pantos

    Saturday, June 30, 2012 12:31 PM
  • Hi

    The link the you have posted only help me to insert some data in azure tables.

    Actually i have made a web client application in which first user have to register and fill some personal information and all the information is stored in azure tables as an extension i have to let the user only login from there windows phone and see the information that they have entered when they used the web client application. For that i have to access the azure tables from windows phone. So REST API seems to be a good option bu tin the link that you have mentioned above i am not able to use that to access my tables that i have created earlier.

    BR & Thank You

    Saturday, June 30, 2012 12:43 PM
  • Hi,

    Base on my understanding, unless you require users to provide their own Windows Azure storage account, please do NOT connect to table storage directly from Windows Phone. Otherwise you have to embed your storage account in the phone application, and a hacker can extract the information and gain full control over your storage account. For instance, he may store several TB data in your storage account and let you pay for them.

    Instead, please create a hosted service that works with your storage account. Let your Windows Phone application communicate via the service rather than the storage account itself. Do not share your storage account with anyone else.

    Hope this helps.


    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework

    • Marked as answer by Arwind - MSFT Friday, July 06, 2012 6:22 AM
    • Unmarked as answer by twoface21 Sunday, July 15, 2012 2:20 PM
    Monday, July 02, 2012 8:50 AM
  • Working code.The below mentioned code is completely working and Mr. Arwind  even i know what your are saying and i asked for answer to my question not some other way of doing it . Btw thank you

    private void GetEntity2(String tableName, String partitionKey, String rowKey)
            {
                String requestMethod = "GET";

                String urlPath = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')", tableName, partitionKey, rowKey);

                String storageServiceVersion = "2009-09-19";

                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
                String stringToSign = String.Format(
                      "{0}\n\n\n{1}\n{2}",
                      requestMethod,
                      dateInRfc1123Format,
                      canonicalizedResource);
                String authorizationHeader = CreateAuthorizationHeader(stringToSign);

                Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers["x-ms-date"] = dateInRfc1123Format;
                request.Headers["x-ms-version"] = storageServiceVersion;
                request.Headers["Authorization"] = authorizationHeader;
                request.Headers["Accept-Charset"] = "UTF-8";
                request.Accept = "application/atom+xml,application/xml";
                request.Headers["DataServiceVersion"] = "1.0;NetFx";
                request.Headers["MaxDataServiceVersion"] = "1.0;NetFx";
                GetResponse(request);
            }

        public void GetResponse(HttpWebRequest request)
            {
                var dataReady = new AutoResetEvent(false);
                HttpWebResponse response = null;
                var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
                {
                    try
                    {              
                        response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                        Stream dataStream = response.GetResponseStream();
                        using (StreamReader reader = new StreamReader(dataStream))
                        {
                            String responseFromServer = reader.ReadToEnd();
                            this.Dispatcher.BeginInvoke(delegate
                            {
                               MessageBox.Show(responseFromServer);

                            });
                        }
                    }
                    

                    dataReady.Set();
                });

                request.BeginGetResponse(callback, request);


            }




      private String CreateAuthorizationHeader(String canonicalizedString)
            {
                String signature = string.Empty;
                using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key)))
                {
                    Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
                    signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                }

                String authorizationHeader = String.Format(
                       CultureInfo.InvariantCulture,
                       "{0} {1}:{2}",
                       AzureStorageConstants.SharedKeyAuthorizationScheme,
                       AzureStorageConstants.Account,
                       signature);

                return authorizationHeader;
            }



    public static class AzureStorageConstants
            {

                private static String TableAccount = "account name";
                private static String cloudEndPointFormat = "http://" + StorageAccount + ".table.core.windows.net/";

                private static String cloudKey = "account key";
                private static string AzureStorage_SharedKeyAuthorizationScheme = "SharedKey";

                public static String Account
                {
                    get { return TableAccount; }
                }

                public static string SharedKeyAuthorizationScheme
                {
                    get { return AzureStorage_SharedKeyAuthorizationScheme; }
                }

                public static string Key
                {
                    get { return cloudKey; }
                }

                public static String TableEndPoint
                {
                    get { return cloudEndPointFormat; }
                }

            }

    • Marked as answer by twoface21 Sunday, July 15, 2012 2:20 PM
    Sunday, July 15, 2012 2:20 PM