将 Dictionary<string, object> 传递给 AWS Lambda 将其序列化为 Dictionary<string, JsonElement>
Passing Dictionary<string, object> to AWS Lambda serializes it to Dictionary<string, JsonElement>
我的 AWS Step Function 将自定义对象从 Lambda 传递到 Lambda。该对象的属性之一是 Dictionary<string, object>
——但 AWS JSON 序列化器变成了类似 Dictionary<string, JsonElement>
的东西。因此,如果我将一个对象传递给它,Newtonsoft 将像这样反序列化:
{ "name": "Tom", "age": 99, "married": true }
...Lambda 接收的输入参数是这样的:
{
"name" : { "ValueKind": 3 },
"age" : { "ValueKind": 2 },
"married" : {"ValueKind: 1 }
}
(忽略我的 ValueKind 价值观,它们并不重要。)
这意味着我的 Lambda 的输入不可用。
我不想为我的 Step Function 中的所有 10+ Lambda 编写和维护一堆翻译器代码来勾选字典中的每个条目并重新构造它。 (无论如何,我不确定是否可以。我认为当它像这样反序列化时,原始值会丢失。)
建议?我可以将 Amazon JSON 序列化程序换成 Newtonsoft 的吗?我可以创建一个对我有帮助的扩展吗?
Can I swap out the Amazon JSON Serializer for Newtonsoft's?
看起来你可以 - 查看 AWS documentation:
Unless your function input and output parameters are of type System.IO.Stream, you will need to serialize them. AWS Lambda provides a default serializer that can be applied at the assembly or method level of your application, or you can define your own by implementing the ILambdaSerializer interface provided by the Amazon.Lambda.Core library. For more information, see Deploy C# Lambda functions with .zip file archives.
To add the default serializer attribute to a method, first add a dependency on Amazon.Lambda.Serialization.Json in your .csproj file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>AssemblyName</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="1.2.0" />
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.3.0" />
<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>
</Project>
它们还包括一个示例,说明如何指定哪种方法使用哪种序列化程序:
public class ProductService{
[LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
public Product DescribeProduct(DescribeProductRequest request)
{
return catalogService.DescribeProduct(request.Id);
}
[LambdaSerializer(typeof(MyJsonSerializer))]
public Customer DescribeCustomer(DescribeCustomerRequest request)
{
return customerService.DescribeCustomer(request.Id);
}
}
他们还建议 .NET Core 3.1 项目(大概是更高版本)使用 their serializer,它利用了 System.Text.Json
以最小化冷启动性能:
If targeting .NET Core 3.1 this serializer is highly recommend over Amazon.Lambda.Serialization.Json and can significantly reduce cold start performance in Lambda.
我找到的最佳答案是 this from Josef Ottosson。
我尝试制作自己的字典,它会询问每个新的 Key/Value 对,并将每个条目放入内部仅字符串字典或仅长字符串字典,因此避免将任何数据存储为 object
。但没有任何效果。
令我高兴的是,这篇文章恰好解决了我的问题 space:如何 de/serialize 具有 Dictionary<string, object>
属性的对象。他创建了一个可以解决问题的 JsonConverterAttribute
。
我的 AWS Step Function 将自定义对象从 Lambda 传递到 Lambda。该对象的属性之一是 Dictionary<string, object>
——但 AWS JSON 序列化器变成了类似 Dictionary<string, JsonElement>
的东西。因此,如果我将一个对象传递给它,Newtonsoft 将像这样反序列化:
{ "name": "Tom", "age": 99, "married": true }
...Lambda 接收的输入参数是这样的:
{
"name" : { "ValueKind": 3 },
"age" : { "ValueKind": 2 },
"married" : {"ValueKind: 1 }
}
(忽略我的 ValueKind 价值观,它们并不重要。)
这意味着我的 Lambda 的输入不可用。
我不想为我的 Step Function 中的所有 10+ Lambda 编写和维护一堆翻译器代码来勾选字典中的每个条目并重新构造它。 (无论如何,我不确定是否可以。我认为当它像这样反序列化时,原始值会丢失。)
建议?我可以将 Amazon JSON 序列化程序换成 Newtonsoft 的吗?我可以创建一个对我有帮助的扩展吗?
Can I swap out the Amazon JSON Serializer for Newtonsoft's?
看起来你可以 - 查看 AWS documentation:
Unless your function input and output parameters are of type System.IO.Stream, you will need to serialize them. AWS Lambda provides a default serializer that can be applied at the assembly or method level of your application, or you can define your own by implementing the ILambdaSerializer interface provided by the Amazon.Lambda.Core library. For more information, see Deploy C# Lambda functions with .zip file archives.
To add the default serializer attribute to a method, first add a dependency on Amazon.Lambda.Serialization.Json in your .csproj file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>AssemblyName</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="1.2.0" />
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.3.0" />
<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>
</Project>
它们还包括一个示例,说明如何指定哪种方法使用哪种序列化程序:
public class ProductService{
[LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
public Product DescribeProduct(DescribeProductRequest request)
{
return catalogService.DescribeProduct(request.Id);
}
[LambdaSerializer(typeof(MyJsonSerializer))]
public Customer DescribeCustomer(DescribeCustomerRequest request)
{
return customerService.DescribeCustomer(request.Id);
}
}
他们还建议 .NET Core 3.1 项目(大概是更高版本)使用 their serializer,它利用了 System.Text.Json
以最小化冷启动性能:
If targeting .NET Core 3.1 this serializer is highly recommend over Amazon.Lambda.Serialization.Json and can significantly reduce cold start performance in Lambda.
我找到的最佳答案是 this from Josef Ottosson。
我尝试制作自己的字典,它会询问每个新的 Key/Value 对,并将每个条目放入内部仅字符串字典或仅长字符串字典,因此避免将任何数据存储为 object
。但没有任何效果。
令我高兴的是,这篇文章恰好解决了我的问题 space:如何 de/serialize 具有 Dictionary<string, object>
属性的对象。他创建了一个可以解决问题的 JsonConverterAttribute
。