1

我有一个关于 Windows Azure 存储队列错误/访问的非常基本的问题。

我试图找出给定的存储帐户是否已经包含给定名称的队列 - 比如说“queue1”。如果队列不存在,我不想创建它,因此我不热衷于使用该CreateIfNotExist方法。我赋予 SAS 令牌的权限是 - 处理和添加(因为我要做的就是仅在队列已经存在时向队列添加新消息,否则抛出错误)

问题是,当我尝试获取对假命名队列的引用并向其中添加消息时,我得到一个 403。当 SAS 令牌没有权限时也可能发生 403,所以我不能确定是什么导致了错误。

有没有办法可以明确知道队列是否存在?

我已经尝试过BeginExist, 和EndExist方法,但即使我可以看到队列在那里,它们也总是返回 false 。

有什么建议么?

4

4 回答 4

2

如果队列存在,Get Queue Metadata则 REST API 操作将返回状态代码 200,否则返回队列服务错误代码

关于授权,

此操作可由帐户所有者和任何具有共享访问签名且有权执行此操作的人执行。

一个 GET 请求

https://myaccount.queue.core.windows.net/myqueue?comp=metadata

将返回如下响应:

Response Status:
HTTP/1.1 200 OK

Response Headers:
Transfer-Encoding: chunked
x-ms-approximate-messages-count: 0
Date: Fri, 16 Sep 2011 01:27:38 GMT
Server: Windows-Azure-Queue/1.0 Microsoft-HTTPAPI/2.0
于 2013-08-03T12:57:30.570 回答
1

即使队列不存在,您确定收到 403 错误。根据您上面描述的内容,我创建了一个简单的控制台应用程序。我的存储帐户中不存在该队列。当我尝试使用有效的 SAS 令牌添加消息时,我收到 404 错误:

    CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("account", "key"), false);
    CloudQueueClient client = storageAccount.CreateCloudQueueClient();
    CloudQueue queue = client.GetQueueReference("non-existent-queue");
    var queuePolicy = new SharedAccessQueuePolicy();
    var sas = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30),
        Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Update
    }, null);
    StorageCredentials creds = new StorageCredentials(sas);
    var queue1 = new CloudQueue(queue.Uri, creds);
    try
    {
        queue1.AddMessage(new CloudQueueMessage("This is a test message"));
    }
    catch (StorageException excep)
    {
        //Get 404 error here
    }

接下来,我通过将其到期时间设置为当前时间前 30 分钟使 SAS 令牌无效。现在,当我运行应用程序时,我得到了预期的 403 错误。

    CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("account", "key"), false);
    CloudQueueClient client = storageAccount.CreateCloudQueueClient();
    CloudQueue queue = client.GetQueueReference("non-existent-queue");
    var queuePolicy = new SharedAccessQueuePolicy();
    var sas = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(-30),//-30 to ensure SAS is invalid
        Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Update
    }, null);
    StorageCredentials creds = new StorageCredentials(sas);
    var queue1 = new CloudQueue(queue.Uri, creds);
    try
    {
        queue1.AddMessage(new CloudQueueMessage("This is a test message"));
    }
    catch (StorageException excep)
    {
        //Get 403 error here
    }
于 2013-08-02T18:53:15.303 回答
1

现在有一个Existsand ExistsAsync(有各种重载)。

前者的使用示例:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

        CloudQueue queue = queueClient.GetQueueReference(queueName);

        bool doesExist = queue.Exists();

您将需要参考Microsoft.Azure.Storage.Queue(我相信较旧的“云”程序集可能没有这些属性 - 最初我只能ExistsAsync在引用正确的包之前访问,一旦我通过 Nuget 添加了上述内容Exists也可用)

有关更多详细信息,请参阅以下链接:

于 2020-04-23T15:23:31.063 回答
0

也没有Exists方法v12。写了一个简单的辅助方法来做检查:

        private async Task<bool> QueueExistsAsync(QueueClient queue)
        {
            try
            {
                await queue.GetPropertiesAsync();
                return true;
            }
            catch (RequestFailedException ex)
            {
                if (ex.Status == (int) HttpStatusCode.NotFound)
                {
                    return false;
                }

                throw;
            }
        }
于 2020-01-21T13:59:51.073 回答