Updated [12/10/13] : The issues detailed in this blog have been resolved via updates to the service and the client library. The client table issue regarding the cast operator (issue 2 below) has been addressed in the 2.1.0.4 and 3.x client releases which are currently available on nuget and github.
In preparation for a major feature release such as CORS, JSON etc. we are pushing an update to production that introduced some bugs. We were notified recently about these bugs and plan to address in an upcoming hotfix. We will update this blog once the fixes are pushed out.
Windows Azure Blobs, Tables and Queue Shared Access Signature (SAS)
One of our customers reported an issue that SAS with version 2012-02-12 failed with HTTP Status Code 400 (Bad Request). Upon investigation, the issue is caused by the fact that our service had a change in how “//” gets interpreted when such sequence of characters appear before the container.
Example: http://myaccount.blob.core.windows.net//container/blob?sv=2012-02-12&si=sasid&sx=xxxx
Whenever it receives a SAS request with version 2012-02-12 or prior, the previous version of our service collapses the ‘//’ into ‘/’ and hence things worked fine. However, the new service update returns 400 (Bad Request) because it interprets the above Uri as if the container name is null which is invalid. We will be fixing our service to revert back to the old behavior and collapse ‘//’ into ‘/’ for 2012-02-12 version of SAS. In the meantime, we advise our customers to refrain from sending ‘//’ at the start of the container name portion of the URI.
Windows Azure Tables
Below are 2 known issues that we intend to hotfix either on the service side or as part of our client library as noted below:
1. When clients define DataServiceContext.ResolveName and in case they provide a type name other than <Account Name>.<Table Name>, the CUD operations will return 400 (Bad Request). This is because ATOM “Category” element with “term” must either be omitted or be equal to the <Account Name>.<Table Name> as part of the new update. Previous version of the service used to ignore any type name being sent. We will be fixing this to again ignore what is being sent, but until then client applications would need to consider the below workaround. The ResolveName is not required for Azure Tables and client application can remove it to ensure that OData does not send “category” element.
Here is an example of a code snippet that would generate a request that fails on the service side:
CloudTableClient cloudTableClient = storageAccount.CreateCloudTableClient();
TableServiceContext tableServiceContext = cloudTableClient.GetDataServiceContext();
tableServiceContext.ResolveName = delegate(Type entityType)
{
// This would cause class name to be sent as the value for term in the category element and service would return Bad Request.
return entityType.FullName;
};
SimpleEntity entity = new SimpleEntity("somePK", "someRK");
tableServiceContext.AddObject("sometable", entity);
tableServiceContext.SaveChanges();
To mitigate the issue on the client side, please remove the highlighted “tableServiceContext.ResolveName” delegate.
We would like to thank restaurant.com for bringing this to our attention and helping us in investigating this issue.
2. The new .NET WCF Data Services library used on the server side as part of the service update rejects empty “cast” as part of the $filter query with 400 (Bad Request) whereas the older .NET framework library did not. This impacts Windows Azure Storage Client Library 2.1 since the IQueryable implementation (see this post for details) sends the cast operator in certain scenarios.
We are working on fixing the client library to match .NET’s DataServiceContext behavior which does not send the cast operator and this should be available in the next couple of weeks. In the meantime we advise our customers to consider the following workaround.
This client library issue can be avoided by ensuring you do not constrain the type of enumerable to the ITableEntity interface but to the exact type that needs to be instantiated.
The current behavior is described by the following example:
static IEnumerable<T> GetEntities<T>(CloudTable table) where T : ITableEntity, new()
{
IQueryable<T> query = table.CreateQuery<T>().Where(x => x.PartitionKey == "mypk");
return query.ToList();
}
The above code in 2.1 storage client library’s IQueryable interface will dispatch a query that looks like the below Uri that is rejected by the new service update with 400 (Bad Request).
http://myaccount.table.core.windows.net/invalidfiltertable?$filter=cast%28%27%27%29%2FPartitionKey%20eq%20%27mypk%27&timeout=90 HTTP/1.1
As a mitigation, consider replacing the above code with the below query. In this case the cast operator will not be sent.
IQueryable<SimpleEntity> query = table.CreateQuery<SimpleEntity>().Where(x => x.PartitionKey == "mypk");
return query.ToList();
The Uri for the request looks like the following and is accepted by the service.
We apologize for these issues and we are working on a hotfix to address them.
Windows Azure Storage Team
I am running elmah on table storage and initializing like this:
// this.connectionString = UseDevelopmentStorage=true
CloudStorageAccount.Parse(this.connectionString).CreateCloudTableClient().GetTableReference("elmaherrors").CreateIfNotExists();
I am also seeing the 400 error but everything was working fine with v2.3. Would this workaround also apply to me?
@John K
Please see blogs.msdn.com/…/windows-azure-storage-release-introducing-cors-json-minute-metrics-and-more.aspx
Storage Emulator Guidance
As mentioned above an updated Windows Azure Storage Emulator is expected to ship with full support of these new features in the next couple of months. Users attempting to develop against the current version of the Storage emulator will receive Bad Request errors as the protocol version (2013-08-15) is unsupported. Until then, users wanting to use the new features would need to develop and test against a Windows Azure Storage Account to leverage the 2013-08-15 REST version.
For users developing against the Storage Emulator in Windows Azure SDK 2.2 you will need to utilize a 2.x version of the Storage Client assembly. Windows Azure SDK 2.2 shipped with Storage Client Library version 2.1.0.2, however we recommend updating that to 2.1.0.4 (using this command in the Package manager console : Install-Package WindowsAzure.Storage –Version 2.1.0.4) as it contains important fixes for the table issue described here: blogs.msdn.com/…/windows-azure-storage-known-issues-november-2013.aspx