Reputation: 2353
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
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
Reputation: 9323
When creating an entity, you have three choices:
http://myaccount.table.core.windows.net/mytable
http://myaccount.table.core.windows.net/mytable(PartitionKey="myPartitionKey", RowKey="myRowKey1")
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:
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
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