You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Azure APIM将带文件名的Multipart表单数据附件存入Azure存储账户

解决APIM处理Multipart/form-data元数据提取与Blob存储/返回问题

一、POST上传时提取元数据并存储到Blob

在APIM的入站(inbound)策略中完成以下操作:

  1. 提取请求的boundary
    从请求头的Content-Type中解析出boundary值,用于后续解析multipart内容:
<set-variable name="boundary" value="@{
    var contentType = context.Request.Headers.GetValueOrDefault("Content-Type", "");
    var boundaryParts = contentType.Split(';').Where(s => s.Trim().StartsWith("boundary=")).ToList();
    return boundaryParts.Any() ? boundaryParts[0].Trim().Substring(9) : string.Empty;
}" />
  1. 解析multipart/form-data,提取name和filename
    读取请求体内容,通过正则匹配content-disposition字段中的name和filename:
<set-variable name="formDataMetadata" value="@{
    var body = context.Request.Body.As<string>(true);
    var boundary = context.Variables.GetValueOrDefault<string>("boundary");
    var partRegex = new System.Text.RegularExpressions.Regex($"--{System.Text.RegularExpressions.Regex.Escape(boundary)}\\r\\ncontent-disposition: form-data; name=\"(?<name>[^\"]+)\"; filename=\"(?<filename>[^\"]+)\"");
    var match = partRegex.Match(body);
    return new {
        Name = match.Groups["name"].Value,
        Filename = match.Groups["filename"].Value,
        Extension = System.IO.Path.GetExtension(match.Groups["filename"].Value).TrimStart('.').ToLower(),
        CreatedAt = DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.ff"),
        UpdatedAt = DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.ff")
    };
}" />
  1. 将元数据附加到Blob存储请求
    调用Azure Storage的Put Blob API时,添加自定义元数据头,同时转发请求体到存储账户:
<set-header name="x-ms-meta-name" exists-action="override">
    <value>@((context.Variables.GetValueOrDefault<dynamic>("formDataMetadata")).Name)</value>
</set-header>
<set-header name="x-ms-meta-filename" exists-action="override">
    <value>@((context.Variables.GetValueOrDefault<dynamic>("formDataMetadata")).Filename)</value>
</set-header>
<set-header name="x-ms-meta-extension" exists-action="override">
    <value>@((context.Variables.GetValueOrDefault<dynamic>("formDataMetadata")).Extension)</value>
</set-header>
<set-header name="x-ms-meta-createdAt" exists-action="override">
    <value>@((context.Variables.GetValueOrDefault<dynamic>("formDataMetadata")).CreatedAt)</value>
</set-header>
<set-header name="x-ms-meta-updatedAt" exists-action="override">
    <value>@((context.Variables.GetValueOrDefault<dynamic>("formDataMetadata")).UpdatedAt)</value>
</set-header>
<rewrite-uri template="/{your-container-name}/{your-blob-name}" />

二、GET检索时构造指定格式的响应

在APIM的出站(outbound)策略中处理返回结果:

  1. 读取Blob元数据和内容
    从Storage的响应头中提取自定义元数据,同时将Blob内容转换为Base64:
<set-variable name="blobMetadata" value="@{
    return new {
        AttachmentName = context.Response.Headers.GetValueOrDefault("x-ms-meta-filename", ""),
        AttachmentType = context.Response.Headers.GetValueOrDefault("x-ms-meta-extension", ""),
        CreatedAt = context.Response.Headers.GetValueOrDefault("x-ms-meta-createdAt", ""),
        UpdatedAt = context.Response.Headers.GetValueOrDefault("x-ms-meta-updatedAt", "")
    };
}" />
<set-variable name="blobBase64" value="@{
    var content = context.Response.Body.As<byte[]>(true);
    return Convert.ToBase64String(content);
}" />
  1. 构造JSON响应
    替换原始响应为要求的JSON格式:
<set-body>@{
    var metadata = context.Variables.GetValueOrDefault<dynamic>("blobMetadata");
    var base64 = context.Variables.GetValueOrDefault<string>("blobBase64");
    return Newtonsoft.Json.JsonConvert.SerializeObject(new {
        attachmentName = metadata.AttachmentName,
        attachmentType = metadata.AttachmentType,
        attachmentData = base64,
        createdAt = metadata.CreatedAt,
        updatedAt = metadata.UpdatedAt
    });
}</set-body>
<set-header name="Content-Type" exists-action="override">
    <value>application/json</value>
</set-header>

注意事项

  • 确保APIM策略中使用As<string>(true)或As<byte[]>(true)读取请求/响应体时,保留原始内容供后续处理。
  • 如果存在多个form-data部分,需调整正则表达式定位目标文件对应的部分。
  • Blob名称可结合业务规则生成(如filename+时间戳),避免重复覆盖。

内容的提问来源于stack exchange,提问作者etrnllrnr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:23:11