I am using REST API to merge an entity into a table storage.
I always got a exception 400 bad request. I checked the request body and header, they all look good. I have If-Match header set to "*". The row existing in the table. I cannot figure out the reason. Can any body give me any advice on how to debug this
kind of exception? How I can get more information rather then the 400 bad request?
It should at least narrow you down to a couple of possibilities.
A good thing to note is alot of the REST based api is Case Sensitive, one thing I would do is check to make sure you don't have a case mismatch between the table name in storage and the table name you are sending with your request.
You could also mock the expected results up with
Fiddler, this will allow you to see how things are going over the wire. Then you can make your API Call with your code to see if the results are the same.
Cory Fowler Windows Azure MVP http://blog.syntaxc4.net
I find Fiddler invaluable in this type of situation. I also find something like
Cloud Storage Studio really useful since it is surprising how often I had goofed with the casing of names which, as Cory points out, is crucial.
I am assuming this is against the real cloud service. I agree with Cory and Neil - fiddler or wireshark is your friend here.
Some common reasons are:
1> date time property should be initialized - the minimum value can be got using DateTime.FromFileTimeUtc(0). This value is different from .NET's minimum value
2> Unsupported data type being sent. The above link also has the data types supported
3> key values cannot be updated
4> Each entity has a 1 MB size limit
5> byte and string can be upto 64KB in size
6> You can have upto 252 custom properties and property names should follow naming rules of c# identifiers
Also, as Cory mentioned, table names are case insensitive but column names are case sensitive. If the case changes for property names, the update will succeed but will add a new property with the specified case.
If it is none of the above, feel free to paste the entity xml sent over the wire and one of us can help spot it.
After quite a few large cup of coffee, I guess the problem may be the key name change (property name). The entity doesn't have a property, but when I update I am adding a new property, do you think this is the major issue?
From those code above, the IfMatch = "*" is passed through to MessageSingaure, but the problem is here: IsTableStorage is true, the IfMatch header is not used. I think this is the real problem.
The code is got from this forum somewhere. I think it is out of date. I do not know how to fix this by adding the IfMatch to header for table storage. What is the correct format of MessageSignature for table storage? Thanks
Is there a reason for not using the official Storage client library which takes care of this?
You would need to add the header in the table storage too. but the problem is with etag format. You would need to conform to the OData format. The storage client library that comes with SDK handles these nuances for you and is built over WCF data Services
.NET (aka OData implementation).
I changed the way how to sign the Auth. Now see the fiddler output
MERGE http://eachcloud2.table.core.windows.net/DocSegEntities(PartitionKey='a3a26ceb-f30e-4663-9856-54b906367adc_5611229341039076683',RowKey='S_0000000000_0000000037') HTTP/1.1
x-ms-date: Fri, 27 May 2011 23:25:19 GMT
Authorization: SharedKey eachcloud2:gCs375e68bZQMFaw6nf7uwxCumRfFJ1T7kV3jGOZ2WQ=
<?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>2011-05-27T23:25:19.6624306Z</updated> <author> <name/> </author> <id>http://eachcloud2.table.core.windows.net/DocSegEntities(PartitionKey='a3a26ceb-f30e-4663-9856-54b906367adc_5611229341039076683',RowKey='S_0000000000_0000000037')</id> <content type="application/xml"> <m:properties><d:PartitionKey>a3a26ceb-f30e-4663-9856-54b906367adc_5611229341039076683</d:PartitionKey>
<d:Src>I couldn't type that fast enough #fail</d:Src>
<d:SrcWithTag>I couldn't type that fast enough #fail</d:SrcWithTag>
</m:properties> </content> </entry>
HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Date: Fri, 27 May 2011 23:25:23 GMT
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
From the error message, the authenticate has some problem.
I changed the code of authenticate, here is the code I am using now
HTTP/1.1 400 Bad Request
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
Date: Sat, 28 May 2011 00:37:59 GMT
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
There are only a few headers, which one is in wrong format?
I know this posting is very old now, but I will add a piece of information that I believe will result helpful to other people having the same problem.
The values for booleans have to be in lower case. THE FOLLOWING WILL CAUSE A 400 ERROR: <d:myProperty m:type="Edm.Boolean">False</d:myProperty> because False has a capital F. When replaced by <d:myProperty
m:type="Edm.Boolean>false</d:myProperty> the response will be accepted and pass. It is very easy to fall into this error if you use myBoolean.ToString(). It will capitalize the first letter. Instead you
need to do something like (myBoolean) ? "true" : "false"
when you create the contents of the request.