Richard Astbury
Richard Astbury

Reputation: 2353

404 When Posting to Table Storage

I am attempting to write to Azure Table Storage without using the TableContext and Table ServiceEntity classes, I just want to send raw XML (I want the flexibility of defining the schema on the fly).

When I do this (and sign the request using the method in the SDK) I get a 404. No idea why.

The table exists. I have omitted my credentials, but they are correct in my original code.

The code snippet below illustrates the problem.

Any suggestions are very welcome!

using System.IO;
using System.Net;
using System.Text;
using Microsoft.WindowsAzure.StorageClient.Protocol;

public static class Program
{
    public static void Main()
    {
        Credentials credentials = new Credentials("xxx", @"yyy");
        var uri = string.Format(@"http://{0}.table.core.windows.net/{1}(PartitionKey='{2}',RowKey='{3}')", credentials.AccountName, "TableName", "1", "1");
        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        webRequest.Method = "POST";
        webRequest.Headers.Add("DataServiceVersion", "2.0;NetFx");
        webRequest.Headers.Add("MaxDataServiceVersion", "2.0;NetFx");
        webRequest.ContentType = @"application/atom+xml";
        WriteToRequestStream(uri, webRequest);
        TableRequest.SignRequestForSharedKeyLite(webRequest, credentials);
        var response = webRequest.GetResponse(); // 404 thrown here
    }

    private static void WriteToRequestStream(string uri, HttpWebRequest webRequest)
    {
        var sb = new StringBuilder();
        sb.Append(@"<?xml version='1.0' encoding='utf-8' standalone='yes'?><entry xmlns:d='http://schemas.microsoft.com/ado/2007/08/dataservices' xmlns:m='http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' xmlns='http://www.w3.org/2005/Atom'><title /><updated>2009-03-18T11:48:34.9840639-07:00</updated><author><name /></author><id>");
        sb.Append(uri);
        sb.Append(@"</id><content type='application/xml'><m:properties></m:properties></content></entry>");
        string body = sb.ToString();
        webRequest.ContentLength = body.Length;
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] bytes = encoding.GetBytes(body);
        using (Stream requestStream = webRequest.GetRequestStream())
        {
            requestStream.Write(bytes, 0, bytes.Length);
        }
    }
}

Upvotes: 2

Views: 1834

Answers (3)

Gertjan
Gertjan

Reputation: 529

See type limitations for table storage on https://msdn.microsoft.com/en-us/library/azure/dd179338.aspx . When for instance posting a property with a minimum datatime value it will result in a 404

Upvotes: 1

madd0
madd0

Reputation: 9323

When creating an entity, you have three choices:

  1. Insert in which you POST to http://myaccount.table.core.windows.net/mytable
  2. Insert or Merge in which you MERGE to http://myaccount.table.core.windows.net/mytable(PartitionKey="myPartitionKey", RowKey="myRowKey1")
  3. Insert or Replace in which you PUT to http://myaccount.table.core.windows.net/mytable(PartitionKey="myPartitionKey", RowKey="myRowKey1")

The latter two, however, are not supported by the local emulator.

Additionally, I took a look at the request your code is making using Fiddler, and it's missing the following headers:

  • Authorization
  • Date or x-ms-date
  • x-ms-version

To include the headers correctly, try this code:

var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "PUT";
webRequest.Headers.Add("DataServiceVersion", "2.0;NetFx");
webRequest.Headers.Add("MaxDataServiceVersion", "2.0;NetFx");
webRequest.Headers.Add("x-ms-version", "2011-08-18");
webRequest.ContentType = @"application/atom+xml";
TableRequest.SignRequestForSharedKeyLite(webRequest, credentials);
WriteToRequestStream(uri, webRequest);
var response = webRequest.GetResponse();

Notice how I changed the method to do an Insert or Replace. I also inverted the call to SignRequestForSharedKeyLite and added a x-ms-version header with version 2011-08-18 otherwise Insert or Replace is not supported.

Upvotes: 1

mcollier
mcollier

Reputation: 3719

I think you're missing the 'x-ms-date' header. I believe that header is required (see http://msdn.microsoft.com/en-us/library/windowsazure/dd179433.aspx).

It might be worth checking out http://azurestoragesamples.codeplex.com/ for full examples on using the REST API. Most operations are included there.

Upvotes: 0

Related Questions