- Я отправляю запрос POST на один из моих API управления API Azure.
В этом почтовом запросе есть тело json, которое содержит данные в кодировке base64 (zip-файл), как в этом примере:
{"foo": "bar", "data": "your-base64-string"}
В политике API я хочу отправить отдельный запрос в REST API службы хранилища Azure, чтобы сохранить вышеупомянутую строку base64 в виде zip-файла.
Теперь проблема: я могу успешно отправить запрос в REST API службы хранилища Azure и загрузить полученный 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-файл, но не могу извлечь его содержимое, так как архив был поврежден.
Вот пример строки zip-файла в кодировке base64 (ZIP-файл, содержащий text.txt):
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>
test.txt
файл с этим содержимымThis is a testfile.
? Проблема в том, что вы не должны преобразовывать его обратно в строкуvar ascii = Encoding.ASCII.GetString(bytes);
. Вы должны отправить необработанные байты в api хранилища. не могли бы вы поделиться своим кодом, который выполняет загрузку? - person Thomas   schedule 06.06.2019var ascii = Encoding.ASCII.GetString(bytes)
как в заголовке, так и в теле? получить contentlenght из bytes.Lenght и вернуть массив байтов для тела. - person Thomas   schedule 06.06.2019var bytes = Convert.FromBase64String(base64String); return new StreamContent(new MemoryStream(bytes));
. Хранилище BLOB-объектов принимает файлы любого типа, фокус в том, чтобы сделать это с помощью API Management ^^ - person Thomas   schedule 06.06.2019