Closed brendonparker closed 7 months ago
I'm able to work around this by changing my byte[]
to string
. But not ideal that it may break someone else.
public class AwsLogs
{
[JsonPropertyName("data")]
public string Data { get; set; } // This used to be byte[]
public async Task<CloudWatchLogEvent> ToCloudWatchLogEventAsync()
{
if (Data == null || Data.Length == 0) return null;
using var ms = new MemoryStream(Convert.FromBase64String(Data));
using var decompress = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
return await JsonSerializer.DeserializeAsync<CloudWatchLogEvent>(decompress);
}
}
So at this point, I don't know if there is anything that you want to do to "fix" :) Seems like people may have varying ways they want to handle this behavior
IMO - it should use the default (not add a special ByteArrayConverter) and require people that want otherwise to specify JsonConverter attributes on their props that are byte[]
Another work around was to use a custom Json Serializer:
class CustomLambdaJsonSerializer : DefaultLambdaJsonSerializer
{
public CustomLambdaJsonSerializer() : base(CreateCustomizer) { }
private static void CreateCustomizer(JsonSerializerOptions options)
{
foreach (var converter in options.Converters.OfType<ByteArrayConverter>().ToArray())
{
options.Converters.Remove(converter);
}
}
}
@brendonparker Good afternoon. Thanks for reporting the issue. Looks like the issue is with your custom implementation of CloudWatchLogEvent
POCO class. Per Using Lambda with CloudWatch Logs, the event returns awslogs:data
as encoded string. Hence the POCO class Amazon.Lambda.CloudWatchLogsEvents.CloudWatchLogsEvent is modeled accordingly, with a helper method DecodeData() to return decoded data. The decoded string should essentially be in the format specified in Using Lambda with CloudWatch Logs, so do you have a custom class for decided CloudWatchEvent
? I'm unsure what needs to be changed in this library as you also mentioned variable use cases for different users.
Thanks, Ashish
@ashishdhingra The issue is not with my custom implementation.
The issue is that the System.Text.Json serializer natively will decode a json payload containing a property with a base64 string to a byte[] property.
However, since a custom ByteArrayConverter has been added, it breaks when it runs into the base64 string. This is a new/breaking change that was introduced at some point. The previous version handled this conversion. The new version throws an exception.
@brendonparker ByteArrayConverter
was added in commit b49dfae373538aad2811340cd2a03b478cb59318 3 years ago. Just as a note, AWS documentation mentions awslogs:data
as encoded string.
Since you mentioned it worked previously and it caused issues after the introduction of ByteArrayConverter
, I will review this with the team.
Thanks, Ashish
Hey @brendonparker since the ByteArrayConverter
was added 3 years ago we can't take it now because that would also be breaking change. My guess is we could potentially make the ByteArrayConverter
more flexible and handle the incoming JSON value being a string going to a byte[]
and perform the base 64 decoding. Not sure when we would get to that work but if you are interested in contributing a PR I be happy to review it.
Yes. That approach should work.
I’m largely unimpeded as my work around is that I can change my type from byte[]
to string
and handle the conversion. But I can work on a PR so that other later don’t get bit by this.
The changes have been released in Amazon.Lambda.Serialization.SystemTextJson version 2.4.3. Thanks for your contribution.
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.
Describe the bug
In upgrading from dotnet6 to dotnet8 I upgraded the Amazon.Lambda.Serialization.SystemTextJson from
2.2.0
to2.4.2
After the upgrade, my lambdas which deserialized payloads that were deserializing base64 strings to byte[] started to fail.
Expected Behavior
Should be able to deserialize base64 string as a byte[]. Or at least document on how to configure around this. No breaking changes.
Current Behavior
Reproduction Steps
In my case I am subscribing to CloudWatch log events and parsing logs.
POCOs
Lambda
Payload
Possible Solution
A. Enhance the ByteArrayConverter to handle/detect base64 encoded string rather than only allow array of numbers. B. Allow for configuring the Default lambda serializer, so this converter can be removed.
Additional Information/Context
No response
AWS .NET SDK and/or Package version used
Amazon.Lambda.Serialization.SystemTextJson 2.4.2
Targeted .NET Platform
.NET 8
Operating System and version
AmazonLinux / Lambda