OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
453 stars 159 forks source link

Using Standard Json Serializer - Json.Net or System.Text.Json #477

Open austinheinrichs opened 2 years ago

austinheinrichs commented 2 years ago

Looking at the current implementation, I was wondering if there were plans for supporting either Json.Net or System.Text.Json serializers. The library does not implement a standard Json serializer and only supports DataContract/DataMember attributes for renaming properties, ignores, etc.

A standard serializer would make using the library simpler in many cases, but I have two specific use cases that would really benefit:

  1. Property Names
using System.Runtime.Serialization;

namespace test.app
{
    [DataContract]
    public class TestDocument<T>
    {
        [DataMember(Name = "prop_1")],
        //[JsonProperty("prop_1")]
        //[JsonPropertyName("prop_1")]
        public string Prop1 { get; set; }

        [DataMember(Name = "obj")]
        //[JsonProperty("obj")]
        //[JsonPropertyName("obj")]
        public T Object { get; set; }
    }
}
  1. Json Converters - I did try implementing a custom serializer using https://github.com/OData/WebApi/issues/2271 as a reference, but we found that introducing an override there would also require overriding the URI parser for cases like selects or expands.

Ideally, the library would support implementations using one of these standard Json serializers. Either implementation would be helpful for consistency in data models and serializing more complex types like structs. Json.Net support would be great considering the .Net5 default serializer implementation of System.Text.Json with a fallback of implementing .AddNewtonsoftJson() in cases where other libraries take heavy dependency on Json.Net. We are currently trying to piece together a .Net5 web api project that involves OData, Cosmos and Cosmos Linq queries that is proving difficult without double attributing our data models. Further, custom Json converters that aren't going to be respected are likewise hard to implement. The goal is to be able to control/be flexible with the property names persisted in documentdb outside of PascalCase or camelCase and allow for custom converters where necessary. It appears there is an option to ignore casing, but it is not quite what we need as shown in the above example casing may not be the only deviation. Any guidance would be much appreciated.

corranrogue9 commented 2 years ago

@austinheinrichs , this is a really great idea. I am working on what this would look like for our next big release, and I'm running into two possible issues:

  1. OData is leveraging the context it has about the model when serializing
  2. I'm not sure that OData will necessarily be able to support all of the attributes of the standard implementations

I'm still working out the first part, but for the second part, aside from JsonPropertyName, are there other attributes that you know aren't supported or are supported, but with a different markup?

austinheinrichs commented 2 years ago

@corranrogue9 thank you for taking a look at this. Property naming and custom property serializers were the most important to us so those were the ones I had focused on. I found that Data Contract/Data Member still having support from JSON.Net made it the least common denominator and the only path for not double/triple attributing our model classes. For properties where I was using custom serializers, I ended up having to ignore them entirely from OData when building the EDM. I'm not aware of any System.Text.JSON attributes that are supported or other property naming attributes that work. Hope that answers your question.