Encode string fields in OData output

2019-09-20 18:11发布

问题:

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.

回答1:

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);