如何将 ZIP 文件从 API 管理上传到 Blob 存储
How to upload ZIP File from API Management to Blob Storage
- 我正在向我的一个 Azure Api Management APIs
发送一个 POST 请求
在这个 post 请求中有一个 json 主体,其中包含 base64 编码的数据(zip 文件),如本例所示:
{
"foo": "bar",
"data": "your-base64-string"
}
在 API 策略中,我想向 Azure 存储 REST API 发送一个单独的请求,以将上述 base64 字符串保存为 zip 文件。
现在的问题:
我可以成功地向 Azure 存储 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==
这是我的代码,用于 post 发送给其他人 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>
Azure API Management 现在支持 body:
中的 byte[]
https://azure.microsoft.com/en-us/updates/azure-api-management-update-september-2019
The set-body policy also accepts byte array as body content.
通过在 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);
- 我正在向我的一个 Azure Api Management APIs 发送一个 POST 请求
在这个 post 请求中有一个 json 主体,其中包含 base64 编码的数据(zip 文件),如本例所示:
{ "foo": "bar", "data": "your-base64-string" }
在 API 策略中,我想向 Azure 存储 REST API 发送一个单独的请求,以将上述 base64 字符串保存为 zip 文件。
现在的问题: 我可以成功地向 Azure 存储 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==
这是我的代码,用于 post 发送给其他人 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>
Azure API Management 现在支持 body:
中的 byte[]https://azure.microsoft.com/en-us/updates/azure-api-management-update-september-2019
The set-body policy also accepts byte array as body content.
通过在 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);