我只为API REST编写了4种方法,但我需要的最后一种方法不起作用。这是删除消息队列。我有这段代码:
public static string DeleteMessage(String queueName, string account, byte[] key, string endpoint, string popreceipt,string messageid)
{
string requestMethod = "DELETE";
String urlPath = String.Format("{0}/messages/{1}?popreceipt={2}", queueName,Uri.EscapeDataString(messageid),Uri.EscapeDataString(popreceipt));
String storageServiceVersion = "2009-09-19";
String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
String canonicalizedHeaders = String.Format(
"x-ms-date:{0}\nx-ms-version:{1}",
dateInRfc1123Format,
storageServiceVersion);
String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
//String canonicalizedResource = String.Format("/{0}/{1}\npopreceipt:{2}", account, urlPath, popreceipt);
String stringToSign = String.Format(
"{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}",
requestMethod,
canonicalizedHeaders,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign, account, key);
Uri uri = new Uri(endpoint + urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", storageServiceVersion);
request.Headers.Add("Authorization", authorizationHeader);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
return response.StatusCode.ToString();
}
}
public static string GetMessage(String queueName,string account, byte[] key,string endpoint)
{
string requestMethod = "GET";
String urlPath = String.Format("{0}/messages", queueName);
String storageServiceVersion = "2009-09-19";
String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
String canonicalizedHeaders = String.Format(
"x-ms-date:{0}\nx-ms-version:{1}",
dateInRfc1123Format,
storageServiceVersion );
String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
String stringToSign = String.Format(
"{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}",
requestMethod,
canonicalizedHeaders,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign,account,key);
Uri uri = new Uri(endpoint + urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", storageServiceVersion );
request.Headers.Add("Authorization", authorizationHeader);
request.Accept = "application/atom+xml,application/xml";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
String responseFromServer = reader.ReadToEnd();
return responseFromServer;
}
}
}
GetMessage正常工作且DeleteMessage无效,CreateAuthorithation Headers Code为:
private static String CreateAuthorizationHeader(String canonicalizedString, string account, byte[] key)
{
String signature = string.Empty;
using (HMACSHA256 hmacSha256 = new HMACSHA256(key))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
account,
signature);
return authorizationHeader;
}
我使用“Convert.FromBase64String(AccountSharedKey)”传递KEY,它适用于GetMessage(以及put消息的另一种方法),但这不适用于删除消息。
我在MSDN中看到API,DELETE和GET消息使用相同的参数,但查询字符串传递的参数除外。
解决
问题在于我不会将UriEscape用于Uri字符串中的参数,有时URL有效,有时不会。
答案 0 :(得分:1)
我认为你构建“canonicalizedResource”字符串的方式存在问题。基于此处的文档:http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx(向下滚动到标题为“构造规范化资源字符串”的部分),您不应将Query String参数作为主规范化资源字符串的一部分传递。它们应该单独附上。
您能否看到使用以下作品:
string canonicalizedResource = string.Format("/{0}/{1}/messages/{2}\npopreceipt:{3}", account, queueName, messageid, popreceipt);
希望这有帮助。
答案 1 :(得分:0)
我尝试了以下代码,它对我来说很好。我创建了一个队列,插入一条消息做了一个“GET”消息就可以得到弹出收据然后删除了消息。我在代码中修改的东西只是基于我上面的答案的canonicalizedResource字符串:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.IO;
using System.Security.Cryptography;
using System.Globalization;
namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
string messageId = "<message id e.g. ba9bdbe6-cd10-465d-ab32-90756ea0471d>";
string queueName = "<queue name e.g. abc>";
string accountName = "<your account name>";
string accountKey = "<you account key base64 encoded string>";
string endpoint = "http://accountname.queue.core.windows.net/";
string popreceipt = "<pop receipt e.g. AgAAAAEAAAAAAAAACuMLtGTIzQE=>";
var result = DeleteMessage(queueName, accountName, Convert.FromBase64String(accountKey), endpoint,
popreceipt, messageId);
}
public static string DeleteMessage(String queueName, string account, byte[] key, string endpoint, string popreceipt, string messageid)
{
string requestMethod = "DELETE";
String urlPath = String.Format("{0}/messages/{1}?popreceipt={2}", queueName, Uri.EscapeDataString(messageid), Uri.EscapeDataString(popreceipt));
String storageServiceVersion = "2009-09-19";
String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
String canonicalizedHeaders = String.Format(
"x-ms-date:{0}\nx-ms-version:{1}",
dateInRfc1123Format,
storageServiceVersion);
String canonicalizedResource = string.Format("/{0}/{1}/messages/{2}\npopreceipt:{3}", account, queueName, messageid, popreceipt);
String stringToSign = String.Format(
"{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}",
requestMethod,
canonicalizedHeaders,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign, account, key);
Uri uri = new Uri(endpoint + urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", storageServiceVersion);
request.Headers.Add("Authorization", authorizationHeader);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
return response.StatusCode.ToString();
}
}
private static String CreateAuthorizationHeader(String canonicalizedString, string account, byte[] key)
{
String signature = string.Empty;
using (HMACSHA256 hmacSha256 = new HMACSHA256(key))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
account,
signature);
return authorizationHeader;
}
}
}