问题
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