How do I replace the OData V4 default Json Serializer with NewtonSoft's Json Serializer?

落花浮王杯 提交于 2020-12-29 04:06:31

问题


I have a class that contains a List of DynamicObjects. I have a unit test that confirms that the Newtonsoft Json Serializer/Deserializer handles this correctly. However, the default OData Json Serializer/Deserializer does not.

I implemented my own ODataEdmTypeDeserializer like this:

public class JsonODataEdmTypeDeserializer : ODataEdmTypeDeserializer
{
    public JsonODataEdmTypeDeserializer(ODataPayloadKind payloadKind) : base(payloadKind)
    {
    }

    public JsonODataEdmTypeDeserializer(ODataPayloadKind payloadKind, ODataDeserializerProvider deserializerProvider) : base(payloadKind, deserializerProvider)
    {
    }

    public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
    {
        var data = readContext.Request.Content.ReadAsStringAsync().Result;

        //Call to the NewtonSoft Deserializer
        var ret = JsonConvert.DeserializeObject(data, type);

        return ret;
    }
}  

along with it's DefaultODataDeserializerProvider:

public class JsonODataDeserializerProvider : DefaultODataDeserializerProvider
{
    public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType)
    {
        var kind = GetODataPayloadKind(edmType);

        return new JsonODataEdmTypeDeserializer(kind, this);
    }

    private static ODataPayloadKind GetODataPayloadKind(IEdmTypeReference edmType)
    {
        switch (edmType.TypeKind())
        {
            case EdmTypeKind.Entity:
                return ODataPayloadKind.Entry;
            case EdmTypeKind.Primitive:
            case EdmTypeKind.Complex:
                return ODataPayloadKind.Property;
            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                return collectionType.ElementType().IsEntity() ? ODataPayloadKind.Feed : ODataPayloadKind.Collection;
            default:
                return ODataPayloadKind.Entry;
        }
    }
}

These work correctly, however when I tried to create my own Serialize implementation I ran into a roadblock:

public class JsonODataEntityTypeSerializer : ODataEntityTypeSerializer
{
    public JsonODataEntityTypeSerializer(ODataSerializerProvider serializerProvider)
        : base(serializerProvider)
    {
    }
public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
    {

    }

WriteObject gets called when my controller tries to return the object in question, but I'm not sure what to do here to insert the Newtonsoft Serializer. I downloaded the OData source code and looked through it but I'm not seeing the hooks I need.


回答1:


You have to create a custom DataWriter, for example NewtonsoftJsonDataWriter:ODataWriter.

Have a look there : tutorial-sample-odatalib-custom-payload-format

In the example it's a Csv writer which is implemented, I think you'll then be able to override its methods WriteStart, WriteHeader, WriteEntry and WriteEnd with a simple Json.Convert().




回答2:


Looked for this before, i don't think it's possible. Kinda like it's not possible to add an XML serializer :-(

It is possible in Web Api though



来源:https://stackoverflow.com/questions/33353775/how-do-i-replace-the-odata-v4-default-json-serializer-with-newtonsofts-json-ser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!