none
Azure Storage - Table REST API using HttpClient

    Question

  • So I'm having trouble with getting an async/await version of this working. Say I'm simply trying to get a list of tables and I'm willing to do it synchronously.

    HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
    request.Method = method;
    request.ContentLength = 0;
    request.ContentType = "application/atom+xml";
    request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
    request.Headers.Add("x-ms-version", "2009-09-19");
    request.Headers.Add("DataServiceVersion", "1.0;NetFx");
    request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
    
    Along with the code to authenticate the request yields a header that looks like

    GET http://xyzzzyx.table.core.windows.net/Tables HTTP/1.1
    x-ms-date: Thu, 05 Mar 2015 19:25:48 GMT
    x-ms-version: 2009-09-19
    Content-Type: application/atom+xml
    DataServiceVersion: 1.0;NetFx
    MaxDataServiceVersion: 1.0;NetFx
    Authorization: SharedKey xyzzzyx:Pvb1GY6nO9hkk7HVJ01f1srltis+emef8Ul4rVsKymQ=
    Host: xyzzzyx.table.core.windows.net
    Connection: Keep-Alive

    And it works. Here's an odd thing, though. There is no content but that Content-Type is vital. If I omit setting it, I get a 403. OK. Fair enough; we leave it in.

    Here's the problem.

    Attempting to do this in an asynch/await regime moves us instead to System.Net.Http.HttpClient.

    The problem is getting the Content-Type into the header.

    Again, I know. There is no content. But omitting that Content-Type header is vital in order to avoid having Azure produce a 403.

    And HttpClient is much more demanding and doesn't allow you to set the Content-Type except on the HttpRequest.Content. But attempting to set the content causes a different failure.

    I've tried setting HttpClient.DefaultRequestHeaders and then a GetAsync, and I've tried building the HttpRequestMessage myself and using SendAsync.

    No dice. I can (reasonably) tell it that I'm looking to Accept "application/atom+xml", but no way to tell it that I'm sending null content composed of "application/atom+xml".

    It seems like it's really that Azure shouldn't be using that Header line in the construction of its Authorization fingerprint making it incompatible with HttpClient meaning that I have to use HttpWebRequest with an AsychCallback which seems like a hack.

    I hope I'm just missing something...

    Ideas?

    Thursday, March 5, 2015 8:38 PM

Answers

  • Manu -

    False alarm / problem solved.

    I had found some sample code and it had some bad / over-simplified code which was the root cause of the problem.

    Specifically, it was written in terms of HttpWebRequest and it baked in the "application/atom+xml" into the string to sign for all Table calls. So in that version, the addition of the Content-Type was key to getting the string signatures to match.

    When I moved to HttpClient, and could no longer force the Content-Type in the header, I no longer matched the string I was signing.

    This seems a reasonable spot to note that when the string signature doesn't match for a Storage Blob, it returns the expected string to sign in the response message. Very handy for exactly this kind of problem and unfortunately, Tables don't offer the same feature.

    Thanks!

    - Gilles

    • Marked as answer by G Dignard Saturday, March 7, 2015 3:46 AM
    Saturday, March 7, 2015 3:46 AM

All replies

  • Hi,

    Thank you for posting in here.
    I'm checking on this and will get back at earliest with an update.

    Regards,
    Manu Rekhar
    Friday, March 6, 2015 4:13 PM
    Moderator
  • Manu -

    False alarm / problem solved.

    I had found some sample code and it had some bad / over-simplified code which was the root cause of the problem.

    Specifically, it was written in terms of HttpWebRequest and it baked in the "application/atom+xml" into the string to sign for all Table calls. So in that version, the addition of the Content-Type was key to getting the string signatures to match.

    When I moved to HttpClient, and could no longer force the Content-Type in the header, I no longer matched the string I was signing.

    This seems a reasonable spot to note that when the string signature doesn't match for a Storage Blob, it returns the expected string to sign in the response message. Very handy for exactly this kind of problem and unfortunately, Tables don't offer the same feature.

    Thanks!

    - Gilles

    • Marked as answer by G Dignard Saturday, March 7, 2015 3:46 AM
    Saturday, March 7, 2015 3:46 AM