Azure Blob 放置命令在以前工作时生成错误

本文关键字:工作 错误 Blob 命令 Azure | 更新日期: 2023-09-27 18:30:00

我正在通过我创建的 C# API 将文件从 Cordova 上传到 Azure Blob 存储。最近,上传停止工作。我一直在进行更改,所以我恢复了更改,但问题仍然存在。我已经尽我所能调试了该过程,但我似乎卡住了。

过程

当我想上传文件时,将执行以下步骤:

  1. 有关文件的数据将上传到 Azure SQL。在插入过程中,将生成并返回 SAS 密钥。
  2. 该文件通过 JavaScript 上传到 C# Web API,SAS 密钥随之发送。
  3. Web
  4. API 在本地存储文件,然后使用 SAS 密钥调用 WebClient.UploadFile 方法进行身份验证。
  5. Web API 应返回 200。

错误

该过程的第一部分运行良好。我正确地生成了一个 sas 密钥(有五分钟的窗口 - 我已将其扩展到 15 但没有成功(,并且将文件上传到 C# Web API 的 JavaScript 进展顺利(我在代码中放置了一个断点并验证了所有内容(。当我调用WebClient.UploadFile方法时会出现此问题。它曾经可以毫无问题地工作。现在我收到 403 错误。错误的状态属性显示协议错误。当我在 Fiddler 中运行它时,我得到的响应是:

服务器无法对请求进行身份验证。确保值授权标头的格式正确,包括签名。

签名字段格式不正确。

请求

下面是对我的 Azure 存储帐户的 PUT 调用的原始视图(为保护无辜者而更改了名称(:

https://myappname.blob.core.windows.net/myapp/792b6b3c-d8df-4100-f9be-bbd69be7f307.jpg?se=2014-11-11T19%253A32%253A33Z&sr=b&sp=w&sig=Lk5SiEEaGUwyOjxjUGkIjink26Gwe7VpXMBPw975ZrM%253D

HTTP/1.1 x-ms-blob-type: BlockBlob x-ms-date: 星期二, 11 Nov 2014

19:

17:24 GMT x-ms版本: 2012-02-12 内容类型:

应用程序/八位字节流主机:myappname.blob.core.windows.net

内容长度:74784 预期:100 续

这是我生成的 SAS 密钥:

se=2014-11-11T19%3A32%3A33Z&sr=b&sp=w&sig=Lk5SiEEaGUwyOjxjUGkIjink26Gwe7VpXMBPw975ZrM%3D

《守则》

这是我的 C# 代码:

var client = new WebClient();
client.Headers.Add("x-ms-blob-type", "BlockBlob");
client.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R",
    System.Globalization.CultureInfo.InvariantCulture));
client.Headers.Add("x-ms-version", "2012-02-12");
sas = Request.RequestUri.Query.Substring(Request.RequestUri.Query.IndexOf("sas=") + 4);
startIndex = Request.RequestUri.Query.IndexOf("name=") + 5;
endIndex = Request.RequestUri.Query.IndexOf("&", startIndex);
fileName = Request.RequestUri.Query.Substring(startIndex, endIndex - startIndex);
client.UploadFile(string.Format(@"{0}/{1}?{2}", endpoint, fileName, sas), "PUT", file.LocalFileName);

这是我的JavaScript代码,它通过移动服务在对SQL Azure表的插入调用上运行:

var azure = require('azure');
var qs = require('querystring');
var appSettings = require('mobileservice-config').appSettings;
function insert(item, user, request) {
    // Get storage account settings from app settings. 
    var accountName = appSettings.STORAGE_ACCOUNT_NAME;
    var accountKey = appSettings.STORAGE_ACCOUNT_ACCESS_KEY;
    var host = accountName + '.blob.core.windows.net';
    if ((typeof item.containerName !== "undefined") && (
    item.containerName !== null)) {
        // Set the BLOB store container name on the item, which must be lowercase.
        item.containerName = item.containerName.toLowerCase();
        // If it does not already exist, create the container 
        // with public read access for blobs.        
        var blobService = azure.createBlobService(accountName, accountKey, host);
        blobService.createContainerIfNotExists(item.containerName, {
            publicAccessLevel: 'blob'
        }, function(error) {
            if (!error) {
                // Provide write access to the container for the next 5 mins.        
                var sharedAccessPolicy = {
                    AccessPolicy: {
                        Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
                        Expiry: new Date(new Date().getTime() + 5 * 60 * 1000)
                    }
                };
                // Generate the upload URL with SAS for the new image.
                var sasQueryUrl = 
                blobService.generateSharedAccessSignature(item.containerName, 
                item.resourceName, sharedAccessPolicy);
                // Set the query string.
                item.sasQueryString = qs.stringify(sasQueryUrl.queryString);
                // Set the full path on the new new item, 
                // which is used for data binding on the client. 
                item.imagePath = sasQueryUrl.baseUrl + sasQueryUrl.path;
            } else {
                console.error(error);
            }
            request.execute();
        });
    } else {
        request.execute();
    }
}

就像我说的,在C#/Azure方面,我的知识没有任何变化。我一直在 Cordova 端玩文件上传,但由于文件成功进入 C# Web API,我看不出这将如何成为一个问题。

我的 Azure 存储日志中出现错误,但我不确定这是否真的是一个错误。我收到的错误是创建容器操作上的 409。该消息是 ClientOtherError。我不确定这是否相关的原因是因为createContainerIfNotExist方法。我不确定如果容器已经存在,这是否会产生错误(似乎不应该,但你永远不知道(。

Azure Blob 放置命令在以前工作时生成错误

我在您的请求 URL 中注意到的一件事是%符号被编码为不应该发生的%25。您的请求 URL 应以 %3D 结尾,这是 = 的 URL 编码。

看起来您缺少身份验证标头。请参阅文档:

授权 - 必需。指定身份验证方案、帐户 姓名和签名。有关详细信息,请参阅身份验证 Azure Storage Services。

有关如何设置此标头的详细信息,请参阅此处

编辑:错误,如评论中指出的那样 - "经过身份验证的请求必须包含授权标头。如果未包含此标头,则请求是匿名的,并且只能针对标记为公共访问的容器或 Blob,或者针对已为其提供共享访问签名以进行委派访问的容器、Blob、队列或表成功