• OData – Custom Serialize & Deserialize


    前言

    本来计划用 Custom Serialize 来解决 OData 不支持 [JsonPropertyName] 的问题.

    但是后来发现 Custom Serialize 并不能解决这个问题. Custom Serialize 允许我们在 response 的时候修改输出的 JSON

    但是 $filter=name eq 'test', 在 parse odata query 的时候, JsonPropertyName 也是需要考虑到的.

    而这个领域是无法通过 Custom Serialize & Deserialize 解决的, 所以我走错路了. 

    但还是小小记入一下它吧.

    参考:

    Build formatter extensions in ASP.NET Core OData 8 and hooks in ODataConnectedService

    Custom Serialize

    做一个类并继承 ODataResourceSerializer

    public class MyResourceSerializer : ODataResourceSerializer
    {
        public MyResourceSerializer(IODataSerializerProvider serializerProvider)
            : base(serializerProvider)
        { }
    
        public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
        {
            ODataResource resource = base.CreateResource(selectExpandNode, resourceContext);
            resource.Properties.ToList().ForEach(p => p.Name = p.Name.ToUpper());
            return resource;
        }
    }

    Override 它的方法, 上面是一个把 property name to uppercase 的例子

    接着还需要一个 SerializerProvider 来把上面的 MyResourceSerializer 提供出去

    public class MySerializerProvider : ODataSerializerProvider
    {
        public MySerializerProvider(IServiceProvider serviceProvider)
            : base(serviceProvider)
        { }
    
        public override IODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType.IsEntity() || edmType.IsComplex())
            {
                return new MyResourceSerializer(this);
            }
            return base.GetEdmTypeSerializer(edmType);
        }
    }

    ODataSerializerProvider 内有对应不同类型的 serializer, 比如 Enum

    依据需求替换掉对应的 Serializer.

    最后是把这个 provider register to services provider.

    Custom Deserialize

    和 Serialize 一样, 做一个 deserialize class, 一个 provider, 让后 register to services provider.

    public class MyResourceDeserializer : ODataResourceDeserializer
    {
        public MyResourceDeserializer(IODataDeserializerProvider serializerProvider)
            : base(serializerProvider)
        { }
    
        public override object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            object resource = base.ReadResource(resourceWrapper, structuredType, readContext);
            return resource;
        }
    }
    
    public class MyDeserializerProvider : ODataDeserializerProvider
    {
        public MyDeserializerProvider(IServiceProvider serviceProvider)
            : base(serviceProvider)
        { }
    
        public override IODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType, bool isDelta = false)
        {
            if (edmType.IsEntity() || edmType.IsComplex())
            {
                return new MyResourceDeserializer(this);
            }
    
            return base.GetEdmTypeDeserializer(edmType, isDelta);
        }
    }

    题外话

    [JsonPropertyName] 怎么弄?

    Custom Serialize 无法解决 JsonPropertyName 的问题. 要解决它需要从 ODataConventionModelBuilder 入手.

    要嘛改它内部实现, 要嘛直接改它做出来的 EdmModel. 我目前是暂时不去解决这个问题, 毕竟还没有需求.

  • 相关阅读:
    完整版:资深程序员都了解的代码复用法则
    Shiro学习总结(10)——Spring集成Shiro
    Shiro学习总结(2)——Apache Shiro快速入门教程
    Shiro学习总结(2)——Apache Shiro快速入门教程
    Mysql学习总结(15)——Mysql错误码大全
    Mysql学习总结(15)——Mysql错误码大全
    ActiveMQ学习总结(6)——ActiveMQ集成Spring和Log4j实现异步日志
    ActiveMQ学习总结(6)——ActiveMQ集成Spring和Log4j实现异步日志
    对话:一个工程师在蘑菇街4年的架构感悟
    这种反爬虫手段有点意思,看我破了它!
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15640470.html
Copyright © 2020-2023  润新知