当前位置: 首页 > 知识库问答 >
问题:

如何将ZIP文件从API管理上传到Blob存储

严阳秋
2023-03-14

>

  • 我正在向我的某个 Azure Api 管理 API 发送 POST 请求
  • 在此帖子请求中,有一个 json 正文,其中包含 base64 编码的数据(zip 文件),如以下示例所示:

    {“foo”:“bar”,“data”:“your-base64-string”}

    在API策略中,我想向Azure Storage 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>
    
  • 共有1个答案

    上官砚文
    2023-03-14

    Azure API Management 现在支持 body 中的 byte[]:

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

    设置正文策略还接受字节数组作为正文内容。

    通过在Blob存储中创建一个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); 
    
     类似资料:
    • 在firebase storage的web sdk中,您可以从Blob数据上载图像。我有一个nodeJS应用程序,想将blob数据中的图像上传到我的存储桶中。在文档中,如果运行节点服务器环境,建议使用AdminSDK。但我在firbase存储管理文档中找不到此功能。 这是我的密码:

    • 是否可以创建一个html表单,允许Web用户直接将文件上传到azure blob store,而不使用其他服务器作为中介?S3和GAW blob store都允许这样做,但我找不到对azure blob存储的任何支持。

    • 我正在使用 Pyspark 尝试从 blob 存储中读取 zip 文件。我想在加载后解压缩文件,然后将解压缩的 CSV 写回 Blob 存储。 我正在遵循以下指南,该指南解释了一旦读取如何解压缩文件:https://docs.databricks.com/_static/notebooks/zip-files-python.html 但是它不能解释我是如何从blob中读取zip文件的。我有以下代码

    • 我不熟悉CosmosDb和azure blob存储,因为我需要引用一个从CosmosDb中的文档上传到azure blob存储的文件,并在附件部分使用它来保存元数据。 我知道json元数据结构应该是这样的: 但是如何在将文件上传到azure blob存储时获取对媒体属性的引用,更准确地说,如何将文件从c#上传到azure blob存储并通过将url设置为媒体属性来引用它。

    • 我有一个Azure函数,当一个blob被上传到某个目录时会被触发。它处理一个zip文件。当我用Azure storage explorer将文件上传到容器时,它工作得非常好。当我通过网络API上传它时,它爆炸了。如果我下载了这个文件,它似乎已经损坏,但是,它与源文件大小相同,当我在2个文件之间进行超越比较时,它看起来是相同的(超越比较似乎可以看到zip文件的内容)。 这里是上传代码: 文件可以很好

    • 在我们的应用程序中,我们让用户选择一个文件夹,然后将该文件夹中的所有文件作为多部分格式数据上传到我们的服务器(Azure App Service)。 在Azure blob storage SDK for JS中,我们可以找到上传单个文件的方法。是否有一种方法可以在一个请求中将多个文件上传到Azure Blob容器中的特定文件夹?