• 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. 我目前是暂时不去解决这个问题, 毕竟还没有需求.

  • 相关阅读:
    C#反射动态调用dll中的方法,并返回结果[转]
    DXF与Entity
    c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.ExitThread(); System.Environment.Exit(0);
    DBText除了左右左对齐且上下Base对齐的其对齐点为Position外,其余的都是AlignmentPoint
    C# Cast
    DataGridView选中行按从上到下或从下到上排序
    获取鼠标点相对于各屏幕、窗体和当前控件的位置
    Database本身就有TileMode的属性,我还去写了一个方法,晕!
    不知为什么,Enter键的KeyDown,KeyPress无法捕捉
    利用正则表达式对字符串进行指定替换
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15640470.html
Copyright © 2020-2023  润新知