【问题标题】:How to upload ZIP File from API Management to Blob Storage如何将 ZIP 文件从 API 管理上传到 Blob 存储
【发布时间】:2019-10-21 17:58:36
【问题描述】:
  1. 我正在我的一个 Azure Api Mangement API 上发送 POST 请求
  2. 在这个 post 请求中,有一个包含 base64 编码数据(zip 文件)的 json 正文,如下例所示:

    { “富”:“酒吧”, “数据”:“你的 base64 字符串” }

  3. 在 API 策略中,我想向 Azure 存储 REST API 发送单独的请求,以将上述 base64 字符串保存为 zip 文件。

现在的问题: 我可以通过以下语句成功向 Azure Storage REST API 发送请求并下载生成的 zip 文件:

<set-body>@{
var base64String = (string)context.Variables.GetValueOrDefault<JObject>("body")["data"]) ;
var bytes = Convert.FromBase64String(base64String); 
var ascii = Encoding.ASCII.GetString(bytes); 
return ascii; 
}</set-body> 

问题是,我可以下载并打开 zip 文件,但我无法提取其中的内容,因为存档已损坏。

这是一个 base64 编码的 zip 文件字符串示例(包含 text.txt 的 ZIP 文件):

UEsDBBQAAAAIAL1ZxE7MTbG/EwAAABMAAAAIAAAAdGVzdC50eHQLycgsVgCiRIWS1OKStMycVD0AUEsBAh8AFAAAAAgAvVnETsxNsb8TAAAAEwAAAAgAJAAAAAAAAAAgAAAAAAAAAHRlc3QudHh0CgAgAAAAAAABABgAI8Ac2LUa1QEjwBzYtRrVAZFuI861GtUBUEsFBgAAAAABAAEAWgAAADkAAAAAAA==

这是我将其发布到 Rest API 的代码:

<send-request mode="new" response-variable-name="putStorageRequest" timeout="5" ignore-error="true">
            <set-url>@((string)context.Variables["blobUrl"])</set-url>
            <set-method>PUT</set-method>
            <set-header name="x-ms-date" exists-action="override">
                <value>@((string) context.Variables["date"] )</value>
            </set-header>
            <set-header name="x-ms-version" exists-action="override">
                <value>@((string) context.Variables["version"] )</value>
            </set-header>
            <set-header name="x-ms-blob-type" exists-action="override">
                <value>BlockBlob</value>
            </set-header>
            <set-header name="Content-Type" exists-action="override">
                <value>application/zip</value>
            </set-header>
            <set-header name="Authorization" exists-action="override">
                <value>@{
                        string body = context.Request.Body.As<string>(preserveContent: true);
                        string contentType = "application/zip";
                        var base64String = (string)context.Variables.GetValueOrDefault<JObject>("body")["data"]) ;
            var bytes = Convert.FromBase64String(base64String); 
            var ascii = Encoding.ASCII.GetString(bytes)
                        var contentLength = ascii.Length;
                        var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(context.Variables.GetValueOrDefault<string>("storageKey")) };
                        var payLoad = string.Format("{0}\n\n\n{1}\n\n{2}\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:{3}\nx-ms-version:{4}\n{5}", 
                            "PUT", 
                            contentLength,
                            contentType,
                            context.Variables["date"],
                            context.Variables["version"],
                            "/" + context.Variables.GetValueOrDefault<string>("storageAccountName") + context.Variables.GetValueOrDefault<string>("resource"));
                        return "SharedKey "+ context.Variables.GetValueOrDefault<string>("storageAccountName") + ":" + Convert.ToBase64String(hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(payLoad)));
                    }</value>
            </set-header>
            <set-body>@{
                var base64String = (string)context.Variables.GetValueOrDefault<JObject>("body")["data"]) ;
                var bytes = Convert.FromBase64String(base64String); 
                var ascii = Encoding.ASCII.GetString(bytes); 
                return ascii;         
            }</set-body>
        </send-request>

【问题讨论】:

  • 不确定要上传或下载文件吗?
  • 好的,我明白了,所以 base64 编码的 zip 文件是有效的,并且包含一个带有此内容的 test.txt 文件 This is a testfile. ?问题是您不应该将其转换回字符串var ascii = Encoding.ASCII.GetString(bytes);。您应该将原始字节发送到存储 API。你能分享你上传的代码吗?
  • 那么您可以尝试在标题和正文中删除此行var ascii = Encoding.ASCII.GetString(bytes) 吗?从 bytes.Lenght 获取内容长度并返回正文的字节数组。
  • 在你的身体里你能不能尝试返回一个流:var bytes = Convert.FromBase64String(base64String); return new StreamContent(new MemoryStream(bytes));。 Blob 存储接受任何类型的文件,诀窍是使用 API 管理 ^^
  • 不能用代码处理吗?例如推送到功能应用?

标签: c# xml azure azure-api-management azure-blob-storage


【解决方案1】:

Azure API 管理现在支持正文中的 byte[]:

https://azure.microsoft.com/en-us/updates/azure-api-management-update-september-2019

set-body 策略也接受字节数组作为正文内容。

我的测试成功了,在 Blob-Storage 中创建了一个 zip 文件,下载了它,打开了 zip 文件并打开了包含的文本文件。

使用了以下代码:

            <set-header name="Authorization" exists-action="override">
            <value>@{
                    string body = context.Request.Body.As<string>(preserveContent: true);
                    string contentType = "application/zip";
                    var base64String = (string)context.Variables.GetValueOrDefault<JObject>("body")["data"] ;
                    var bytes = Convert.FromBase64String(base64String); 
                    var contentLength = bytes.Length;
                    var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(context.Variables.GetValueOrDefault<string>("storageKey")) };
                    var payLoad = string.Format("{0}\n\n\n{1}\n\n{2}\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:{3}\nx-ms-version:{4}\n{5}", 
                        "PUT", 
                        contentLength,
                        contentType,
                        context.Variables["date"],
                        context.Variables["version"],
                        "/" + context.Variables.GetValueOrDefault<string>("storageAccountName") + context.Variables.GetValueOrDefault<string>("resource"));
                    return "SharedKey "+ context.Variables.GetValueOrDefault<string>("storageAccountName") + ":" + Convert.ToBase64String(hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(payLoad)));
                }</value>
        </set-header>
        <set-body>@{
            var base64String = (string)context.Variables.GetValueOrDefault<JObject>("body")["data"] ;
            var bytes = Convert.FromBase64String(base64String); 
            return bytes;         
        }</set-body>

我只需要删除:

var ascii = Encoding.ASCII.GetString(bytes); 

【讨论】:

    猜你喜欢
    • 2020-12-16
    • 2019-08-13
    • 2023-03-25
    • 2020-02-02
    • 2021-03-07
    • 2017-01-24
    • 2017-08-19
    • 2014-11-11
    相关资源
    最近更新 更多