Search code examples
serializationasp.net-web-apiodata

Encode string fields in OData output


I have an OData controller that want to encode string fields of its output. OData output result is sent back to client as clear data but I want to encrypt them before sending it to client.

It seems that the best way is to use a customized OData serializer or a feed serializer to achieve my goal. But I'm not sure which class to customize. Is it better to override some methods or implement my own customized version of a serializing class.

Any help is appreciated.


Solution

  • Find a way to do it. I did it by customizing serializer by help of this guide. Final code:

    using Microsoft.Data.Edm;
    using Microsoft.Data.OData;
    using System.Web.Http.OData.Formatter.Serialization;
    
    namespace MyProj
    {
        public class CustomODataEntityTypeSerializer : ODataEntityTypeSerializer
        {
            public CustomODataEntityTypeSerializer(ODataSerializerProvider serializerProvider) : base(serializerProvider)
            {
            }
    
            public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
            {
                //http://odata.github.io/WebApi/#06-03-costomize-odata-formatter
    
                if (graph is CompanyDto)
                {
                    var company = (CompanyDto)graph;
    
                    company.FirstName = Encrypt(company.FirstName);
                    company.LastName = Encrypt(company.LastName);
                }
    
                base.WriteObjectInline(graph, expectedType, writer, writeContext);
            }
        }
    }
    

    And this class:

    using Microsoft.Data.Edm;
    using System.Web.Http.OData.Formatter.Serialization;
    
    namespace MyProj
    {
        public class CustomDefaultODataSerializerProvider : DefaultODataSerializerProvider
        {
            CustomODataEntityTypeSerializer _customODataEntityTypeSerializer;
    
            public CustomDefaultODataSerializerProvider()
            {
                _customODataEntityTypeSerializer = new CustomODataEntityTypeSerializer(this);
            }
    
            public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
            {
                if (edmType.IsEntity())
                {
                    return _customODataEntityTypeSerializer;
                }
    
                return base.GetEdmTypeSerializer(edmType);
            }
        }
    }
    

    And initializing it as follow:

                var odataFormatters = ODataMediaTypeFormatters.Create(new CustomDefaultODataSerializerProvider(), new DefaultODataDeserializerProvider());
            config.Formatters.InsertRange(0, odataFormatters);