英文:
AWS lambda how to create multipart response in .NET Core?
问题
I migrated an existing .NET Core service to AWS Lambda, and I am not sure how to send the correct multipart response from my function.cs
.
原来的.NET Core服务返回了一个IActionResult
并生成了一个多部分响应,包括第一部分的XML和第二部分的64位编码的HTML字符串。
我尝试了不同的返回类型,包括IActionResult
,但都没有产生与原始REST服务相同的多部分输出。使用下面的代码,我的响应是:
{}
我该如何从function.cs
返回以下结构?
多部分响应
--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
中的部分代码:
[HttpPost, Route("/api/Post")]
[Consumes("application/xml", "text/xml", "text/plain", "application/octet-stream", "application/json")]
public async Task<IActionResult> Post(string xmlfile)
{
acordXml = await _gateway.ProcessIncomingRequestAndReturnXMLString(modifiedRequest, logTimeStamp);
string htmlResponse = _gateway.CreateHtmlString(modifiedRequest, logTimeStamp);
return new XmlAndEncodedHtmlMultipartResult().SetEncodedHtmlContent(htmlResponse).SetXmlContent(acordXml);
}
用于在REST中创建多部分响应的XmlAndEncodedHtmlMultipartResult
类:
public class XmlAndEncodedHtmlMultipartResult : IActionResult
{
private StringContent _xmlContent;
private StringContent _htmlContent;
public static string Subtype = "related";//my-xml+html
private MultipartContent _multipartContent = new MultipartContent(Subtype);
public XmlAndEncodedHtmlMultipartResult SetXmlContent(string xml, string contentId = "ACORD")
{
var xmlContent = new StringContent(xml, Encoding.UTF8, "text/xml");
xmlContent.Headers.Add("Content-id", contentId);
this._xmlContent = xmlContent;
return this;
}
public XmlAndEncodedHtmlMultipartResult SetEncodedHtmlContent(string rawHtml, string contentId = "Inquiry.html", string description = "Response to View Inquiry")
{
var bytes = Encoding.UTF8.GetBytes(rawHtml);
var encodedHtml = Convert.ToBase64String(bytes);
var htmlContent = new StringContent(encodedHtml, Encoding.UTF8, "application/html");
htmlContent.Headers.Add("Content-id", contentId);
htmlContent.Headers.Add("Content-description", description);
this._htmlContent = htmlContent;
return this;
}
public async Task ExecuteResultAsync(ActionContext context)
{
this._multipartContent.Add(this._xmlContent);
if(this._htmlContent != null)
this._multipartContent.Add(this._htmlContent);
var response = context.HttpContext.Response;
response.ContentType = this._multipartContent.Headers.ContentType.ToString();
await _multipartContent.CopyToAsync(response.Body);
}
}
(Note: The code samples contain HTML-encoded characters. Please ensure that you handle these correctly when implementing the solution.)
英文:
I migrated an existing .NET Core service to AWS Lambda and I am not sure how to send the correct multipart response from my function.cs
.
The original .NET Core service returned an IActionResult
and produced a multipart response, consisting of a an XML for the first part, and a 64-bit encoded html string for the 2nd part.
I tried various return types including IActionResult
and none of them produce the same multi-part output the original REST service did. Using the code below, my response is:
{}
How do I return the following structure from the function.cs?
Multipart response
--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--
Code snippet from 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;
}
Partial code inside original rest controller function named Post
:
[HttpPost, Route("/api/Post")]
[Consumes("application/xml", "text/xml", "text/plain", "application/octet-stream", "application/json")]
public async Task<IActionResult> Post(string xmlfile)
{
acordXml = await _gateway.ProcessIncomingRequestAndReturnXMLString(modifiedRequest, logTimeStamp);
string htmlResponse = _gateway.CreateHtmlString(modifiedRequest, logTimeStamp);
return new XmlAndEncodedHtmlMultipartResult().SetEncodedHtmlContent(htmlResponse).SetXmlContent(acordXml);
}
XmlAndEncodedHtmlMultipartResult
class used to create multipart response in Rest:
public class XmlAndEncodedHtmlMultipartResult : IActionResult
{
private StringContent _xmlContent;
private StringContent _htmlContent;
public static string Subtype = "related";//my-xml+html
private MultipartContent _multipartContent = new MultipartContent(Subtype);
public XmlAndEncodedHtmlMultipartResult SetXmlContent(string xml, string contentId = "ACORD")
{
var xmlContent = new StringContent(xml, Encoding.UTF8, "text/xml");
xmlContent.Headers.Add("Content-id", contentId);
this._xmlContent = xmlContent;
return this;
}
public XmlAndEncodedHtmlMultipartResult SetEncodedHtmlContent(string rawHtml, string contentId = "Inquiry.html", string description = "Response to View Inquiry")
{
var bytes = Encoding.UTF8.GetBytes(rawHtml);
var encodedHtml = Convert.ToBase64String(bytes);
var htmlContent = new StringContent(encodedHtml, Encoding.UTF8, "application/html");
htmlContent.Headers.Add("Content-id", contentId);
htmlContent.Headers.Add("Content-description", description);
this._htmlContent = htmlContent;
return this;
}
public async Task ExecuteResultAsync(ActionContext context)
{
this._multipartContent.Add(this._xmlContent);
if(this._htmlContent != null)
this._multipartContent.Add(this._htmlContent);
var response = context.HttpContext.Response;
response.ContentType = this._multipartContent.Headers.ContentType.ToString();
await _multipartContent.CopyToAsync(response.Body);
}
}
答案1
得分: 2
不要回答我要翻译的问题。
以下是要翻译的内容:
"Instead of creating a stand-alone Lambda function that serves as a wrapper around the controller endpoint of interest -- you may have better luck instantiating/running your entire NET Core Web API project within a single Lambda function using the AWS provided NuGet package Amazon.Lambda.AspNetCoreServer
and calling your existing endpoint of interest and examining the response."
"Updating an existing ASP.NET Core project to run in Lambda fronted by API Gateway is a very painless process and you should have greater parity with your application's HTTP responses instead of trying to mimic the server response with your Lambda function handler."
"References:
https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md
https://aws.amazon.com/blogs/developer/running-serverless-asp-net-core-web-apis-with-amazon-lambda/"
英文:
Instead of creating a stand-alone Lambda function that serves as a wrapper around the controller endpoint of interest -- you may have better luck instantiating/running your entire NET Core Web API project within a single Lambda function using the AWS provided NuGet package Amazon.Lambda.AspNetCoreServer
and calling your existing endpoint of interest and examining the response.
Updating an existing ASP.NET Core project to run in Lambda fronted by API Gateway is a very painless process and you should have greater parity with your application's HTTP responses instead of trying to mimic the server response with your Lambda function handler.
References:
https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md
https://aws.amazon.com/blogs/developer/running-serverless-asp-net-core-web-apis-with-amazon-lambda/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论