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

如何在.NET Core的AWS Lambda中生成正确的Multipart响应?

问题描述

已将现有.NET Core服务迁移至AWS Lambda,但无法在function.cs中生成正确的Multipart响应。原服务返回IActionResult,生成的多部分响应包含XML和Base64编码的HTML两部分,但Lambda中尝试多种返回类型后,当前仅返回{}。需要生成如下结构的Multipart响应:

--d3742228-85fc-4218-bf24-7e9dec746710
Content-Type: text/xml; charset=utf-8
Content-id: ACORD

<?xml version="1.0" encoding="utf-8"?>
<ACORD>
  <InsuranceSvcRs>
    <Status>
      <StatusCd>0</StatusCd>
      <StatusDesc>Success</StatusDesc>
    </Status>
  </InsuranceSvcRs>
</ACORD>
--d3742228-85fc-4218-bf24-7e9dec746710
Content-Type: application/html; charset=utf-8
Content-id: Inquiry.html
Content-description: Response to View Inquiry

PCFET0NUWVBFIEhUTUwgUFVCTElDICctLy9XM0MvL0RURC=
--d3742228-85fc-4218-bf24-7e9dec746710--

现有function.cs代码片段:

public async Task<IActionResult> FunctionHandler(ApiGatewayRequest.Root input, ILambdaContext context)
{
    IActionResult? ugResult = null;
    var result = controller.Post(apiGatewayRequest.body); //return multip-part response
    ugResult = result.GetAwaiter().GetResult(); 
    return ugResult;
}

原REST控制器Post方法及自定义XmlAndEncodedHtmlMultipartResult类逻辑已在提问中给出。

解决方案

Lambda执行环境与普通ASP.NET Core不同,IActionResult的ExecuteResultAsync依赖ASP.NET Core原生HttpContext,而Lambda中无此上下文,直接返回IActionResult会导致内容无法正确解析,最终返回空对象。需直接构建Multipart内容,返回适配API Gateway的响应结构。

实现步骤

  1. 构建Multipart内容:复用原有的多部分内容生成逻辑,但直接操作MultipartContent对象,无需依赖IActionResult。
  2. 适配API Gateway响应格式:API Gateway要求Lambda返回包含状态码、响应头、Base64编码内容的结构,需自定义响应类或返回符合要求的匿名对象。
  3. 修改Handler返回类型:将IActionResult替换为适配API Gateway的响应类型。

修改后的代码示例

1. 定义API Gateway响应类

public class ApiGatewayResponse
{
    public int StatusCode { get; set; }
    public Dictionary<string, string> Headers { get; set; } = new();
    public string Body { get; set; } = string.Empty;
    public bool IsBase64Encoded { get; set; } = true;
}

2. 重构FunctionHandler逻辑

public async Task<ApiGatewayResponse> FunctionHandler(ApiGatewayRequest.Root input, ILambdaContext context)
{
    // 调用业务逻辑获取XML和HTML原始内容
    var acordXml = await _gateway.ProcessIncomingRequestAndReturnXMLString(modifiedRequest, logTimeStamp);
    string htmlResponse = _gateway.CreateHtmlString(modifiedRequest, logTimeStamp);

    // 构建Multipart内容
    var multipartContent = new MultipartContent(XmlAndEncodedHtmlMultipartResult.Subtype);

    // 添加XML部分
    var xmlContent = new StringContent(acordXml, Encoding.UTF8, "text/xml");
    xmlContent.Headers.Add("Content-id", "ACORD");
    multipartContent.Add(xmlContent);

    // 添加Base64编码的HTML部分
    var htmlBytes = Encoding.UTF8.GetBytes(htmlResponse);
    var encodedHtml = Convert.ToBase64String(htmlBytes);
    var htmlContent = new StringContent(encodedHtml, Encoding.UTF8, "application/html");
    htmlContent.Headers.Add("Content-id", "Inquiry.html");
    htmlContent.Headers.Add("Content-description", "Response to View Inquiry");
    multipartContent.Add(htmlContent);

    // 将Multipart内容转为字节数组
    using var memoryStream = new MemoryStream();
    await multipartContent.CopyToAsync(memoryStream);
    var contentBytes = memoryStream.ToArray();

    // 返回适配API Gateway的响应
    return new ApiGatewayResponse
    {
        StatusCode = 200,
        Headers = new Dictionary<string, string>
        {
            ["Content-Type"] = multipartContent.Headers.ContentType.ToString()
        },
        Body = Convert.ToBase64String(contentBytes),
        IsBase64Encoded = true
    };
}

3. 可选:复用原自定义Result类

如果不想重复代码,可修改XmlAndEncodedHtmlMultipartResult类,添加获取MultipartContent的方法:

public class XmlAndEncodedHtmlMultipartResult : IActionResult
{
    // 原有代码保持不变...

    // 添加获取构建好的MultipartContent的方法
    public MultipartContent GetMultipartContent()
    {
        _multipartContent.Add(_xmlContent);
        if (_htmlContent != null)
            _multipartContent.Add(_htmlContent);
        return _multipartContent;
    }
}

然后在Handler中复用:

public async Task<ApiGatewayResponse> FunctionHandler(ApiGatewayRequest.Root input, ILambdaContext context)
{
    var actionResult = await controller.Post(input.body);
    var multipartResult = actionResult as XmlAndEncodedHtmlMultipartResult;
    if (multipartResult == null)
    {
        return new ApiGatewayResponse { StatusCode = 500 };
    }

    var multipartContent = multipartResult.GetMultipartContent();
    using var memoryStream = new MemoryStream();
    await multipartContent.CopyToAsync(memoryStream);
    var contentBytes = memoryStream.ToArray();

    return new ApiGatewayResponse
    {
        StatusCode = 200,
        Headers = new Dictionary<string, string>
        {
            ["Content-Type"] = multipartContent.Headers.ContentType.ToString()
        },
        Body = Convert.ToBase64String(contentBytes),
        IsBase64Encoded = true
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:07:18