访问 azure 表实体
Posted
技术标签:
【中文标题】访问 azure 表实体【英文标题】:Accessing azure tables entities 【发布时间】:2012-07-01 16:35:07 【问题描述】:大家好,我想使用 REST API 或使用 Odata 从 Windows Phone 。 我写了一个代码,但这给了我 NULL 响应。每次我想访问一个表实体时,我都会调用 GetEntity 函数。下面是我正在使用的代码。 请如果有人知道此代码有什么问题或任何帮助尽快回复。
///////////获取实体函数。/////////
private void GetEntity(String tableName, String partitionKey, String rowKey)
String requestMethod = "GET";
String urlPath = String.Format("0(PartitionKey='1',RowKey='2')", tableName, partitionKey, rowKey);
String dateInRfc1123Format = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
String canonicalizedResource = String.Format("/0/1", AzureStorageConstants.Account, urlPath);
String stringToSign = String.Format(
"0\n\n\n1\n2",
requestMethod,
dateInRfc1123Format,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign);
HttpWebResponse response;
Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers[HttpRequestHeader.ProxyAuthorization] = null;
request.Headers["Address"] = uri.ToString();
request.Headers["Method"] = requestMethod;
request.Headers["x-ms-date"]= DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
request.Headers["x-ms-version"]= "2011-08-18";
request.Headers["Authorization"] = authorizationHeader;
request.Headers["Accept-Charset"] = "UTF-8";
request.Headers["ContentType"] = "application/atom+xml,application/xml";
request.ContentType = "application/atom+xml,application/xml";
request.Headers["DataServiceVersion"] = "1.0;NetFx";
request.Headers["MaxDataServiceVersion"] = "1.0;NetFx";
using (response = GetResponse(request))
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
String responseFromServer = reader.ReadToEnd();
// 获取响应函数。
public HttpWebResponse GetResponse(HttpWebRequest request)
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
dataReady.Set();
);
request.BeginGetResponse(callback, request);
return response;
////// 创建授权函数。///
private String CreateAuthorizationHeader(String canonicalizedString)
String signature = string.Empty;
using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key)))
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"0 1:2",
AzureStorageConstants.SharedKeyAuthorizationScheme,
AzureStorageConstants.Account,
signature);
return authorizationHeader;
////////AzureStorageConstants.
public static class AzureStorageConstants
private static String TableAccount = "datablobs";
private static String cloudEndPointFormat = "http://" + TableAccount + ".table.core.windows.net/";
private static String cloudKey = "Primary Access Key";// Here actual key is written.
private static string AzureStorage_SharedKeyAuthorizationScheme = "SharedKey";
public static String Account
get return TableAccount;
public static string SharedKeyAuthorizationScheme
get return AzureStorage_SharedKeyAuthorizationScheme;
public static string Key
get return cloudKey;
public static String TableEndPoint
get return cloudEndPointFormat;
【问题讨论】:
尝试编辑代码以提高可读性如何?我试着为你做一次,但显然你不喜欢它并回滚了。 你完成了编辑很抱歉给您带来不便。 【参考方案1】:有关解决方案,请参阅下面的链接,我已将解决方案发布在 http://social.msdn.microsoft.com/Forums/en-US/windowsazureconnectivity/thread/84415c36-9475-4af0-9f52-c534f5681432
【讨论】:
【参考方案2】:我检查了您的代码,发现 GetEntity() 函数在创建签名以访问 Windows Azure 表存储方面确实存在一些问题,因此我将以下代码组合在一起,它确实有效。您只需替换您的 GetEntity() 并添加以下代码中包含的另外两个函数即可正常工作签名过程。
private string GetEntity(String tableName, String partitionKey, String rowKey)
string result = "";
String requestMethod = "GET";
String urlPath = String.Format("0(PartitionKey='1',RowKey='2')",tableName, partitionKey, rowKey);
DateTime now = DateTime.UtcNow;
HttpWebResponse response;
string uri = AzureStorageConstants.TableEndPoint + urlPath;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = requestMethod;
request.ContentLength = 0;
request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2009-09-19");
request.ContentType = "application/atom+xml";
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("Authorization", AuthorizationHeader(requestMethod, now, request));
request.Accept = "application/atom+xml";
using (response = request.GetResponse() as HttpWebResponse)
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
result = reader.ReadToEnd();
return result;
public string AuthorizationHeader(string method, DateTime now, HttpWebRequest request)
string MessageSignature;
MessageSignature = String.Format("0\n\n1\n2\n3",
method,
"application/atom+xml",
now.ToString("R", System.Globalization.CultureInfo.InvariantCulture),
GetCanonicalizedResource(request.RequestUri, AzureStorageConstants.Account)
);
byte[] SignatureBytes = System.Text.Encoding.UTF8.GetBytes(MessageSignature);
System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key));
String AuthorizationHeader = "SharedKey " + AzureStorageConstants.Account + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
return AuthorizationHeader;
public string GetCanonicalizedResource(Uri address, string accountName)
StringBuilder str = new StringBuilder();
StringBuilder builder = new StringBuilder("/");
builder.Append(accountName);
builder.Append(address.AbsolutePath);
str.Append(builder.ToString());
NameValueCollection values2 = new NameValueCollection();
NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
foreach (string str2 in values.Keys)
ArrayList list = new ArrayList(values.GetValues(str2));
list.Sort();
StringBuilder builder2 = new StringBuilder();
foreach (object obj2 in list)
if (builder2.Length > 0)
builder2.Append(",");
builder2.Append(obj2.ToString());
values2.Add((str2 == null) ? str2 : str2.ToLowerInvariant(), builder2.ToString());
ArrayList list2 = new ArrayList(values2.AllKeys);
list2.Sort();
foreach (string str3 in list2)
StringBuilder builder3 = new StringBuilder(string.Empty);
builder3.Append(str3);
builder3.Append(":");
builder3.Append(values2[str3]);
str.Append("\n");
str.Append(builder3.ToString());
return str.ToString();
为了解决您与签名相关的问题,我从Storage_REST_CS sample 获取了代码,该代码具有通过 REST 接口访问 Windows Azure(Blob、表和队列)存储的出色实现。
【讨论】:
您好,我正在 Windows 手机上开发此应用程序。所以有些库和方法是不支持的。像 a) 找不到类型或命名空间名称“NameValueCollection”。 b) HttpWebRequest 不包含“内容长度”的定义 c)“System.Net.HttpUtility”不包含“ParseQueryString”的定义 d)“System.Collections.ArrayList”不包含“排序”的定义 e)System .Collections.ArrayList' 不包含带 1 个参数的构造函数 还有一个:System.Collections.ArrayList' 由于其保护级别而无法访问 我们可以使用 List 而不是 ArrayList。 我目前正在研究它。会尽快告诉它是否有效。谢谢 解决方案参考下面的链接我已经在那里发布了解决方案social.msdn.microsoft.com/Forums/en-US/windowsazureconnectivity/…以上是关于访问 azure 表实体的主要内容,如果未能解决你的问题,请参考以下文章
Azure 表存储 - 表服务查询以检索并返回 10 个实体,直到最后一个实体