简体   繁体   中英

Custom Serializer Settings

I am creating a AWS Lambda function which will take a JSON payload and process it. With the C# SDK, they provide a serializer which is based on Newtonsoft.Json.

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

I have a need to specify custom formats for dates so that things can be deserialized properly into a .NET class, among other things.

In Newtonsoft.Json, I can define custom settings like this:

new JsonSerializerSettings()
{
    DateFormatString = "yyyyMMdd",
    Formatting = Formatting.Indented,
    NullValueHandling = NullValueHandling.Ignore
};

I cannot find anywhere in documentation or otherwise how this can be done with the Amazon implementation. Has anyone customized the LambdaSerializer?

Here's a bare bones example:

using System;
using System.Collections.Generic;
using System.IO;

using Amazon.Lambda.Core;

namespace MySerializer
{
    public class LambdaSerializer : ILambdaSerializer
    {

        public LambdaSerializer()
        {
        }


        public LambdaSerializer(IEnumerable<Newtonsoft.Json.JsonConverter> converters) : this()
        {
            throw new NotSupportedException("Custom serializer with converters not supported.");
        }


        string GetString(Stream s)
        {
            byte[] ba = new byte[s.Length];

            for (int iPos = 0; iPos < ba.Length; )
            {
                iPos += s.Read(ba, iPos, ba.Length - iPos);
            }

            string result = System.Text.ASCIIEncoding.ASCII.GetString(ba);
            return result;
        }


        public T Deserialize<T>(Stream requestStream)
        {
            string json = GetString(requestStream);
            // Note: you could just pass the stream into the deserializer if it will accept it and dispense with GetString()
            T obj = // Your deserialization here
            return obj;
        }


        public void Serialize<T>(T response, Stream responseStream)
        {
            string json = "Your JSON here";
            StreamWriter writer = new StreamWriter(responseStream);
            writer.Write(json);
            writer.Flush();
        }

    } // public class LambdaSerializer

}

In your lambda function you'll have this:

[assembly: LambdaSerializer(typeof(MySerializer.LambdaSerializer))]

namespace MyNamespace
{

   public MyReturnObject FunctionHandler(MyInObject p, ILambdaContext context)
   {

   }

Note that explicitly fulfilling the interface doesn't work:

void ILambdaContext.Serialize<T>(T response, Stream responseStream)
{
   // won't work

Don't ask me why. My guess is AWS create the object and don't cast it to the interface but expect public methods.

You can actually find the serializer source code out there, but I can't find it at the moment. If I come across it I'll edit this post.

In my experience only the default ctor is used but to be safe you should probably add their default converters to your serializer. I don't bother at the moment and it's been OK, though.

Hope this helps.

Adam.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM