Webapi: [feature/dotnetcore]: ASP.NET Core OData with custom DefaultODataSerializerProvider

Created on 4 Apr 2018  路  6Comments  路  Source: OData/WebApi

I am trying to implement custom DefaultODataSerializerProvider in Asp.Net Core

Assemblies affected

Microsoft.AspNetCore.OData.dll 7.0.0-Nightly201804041242

Expected result

I need something like:

var formatters = ODataMediaTypeFormatters.Create(
                new CustomODataSerializerProvider(),
                new DefaultODataDeserializerProvider());
config.Formatters.InsertRange(0, formatters);

Actual result

in ASP.NET Core I tried to customize:

services.AddMvcCore(options =>
{
   options.OutputFormatters.Add(new IoTSerializerOutputFormatter());
})

but it is custom IOutputFormatter class.

Question

Could you provide code sample how I can implement custom DefaultODataSerializerProvider in ASP.NET Core with Microsoft.AspNet.OData package ?

Most helpful comment

@GregSem
I want to implement a custom DefaultODataSerializerProvider in ASP.Net Core . Could you provide code sample how I can implement custom DefaultODataSerializerProvider with Microsoft.AspNetCore.OData package?

All 6 comments

#
Ok. I solved it:

app.UseMvc(routeBuilder => {
   routeBuilder.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
   ...
   routeBuilder.MapODataServiceRoute(odata_route_name, route_prefix, a =>
   {
        a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEdmModel), sp => GetEdmModel(app.ApplicationServices));
        a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new CustomSerializerProvider(sp));
         ...
    });
    routeBuilder.EnableDependencyInjection();

@GregSem Since this is solved can you close the Issue

@GregSem
I want to implement a custom DefaultODataSerializerProvider in ASP.Net Core . Could you provide code sample how I can implement custom DefaultODataSerializerProvider with Microsoft.AspNetCore.OData package?

@GregSem Can u share your solution? (Includet the custom DefaultODataSerializerProvider ;) )

After some digging, it appears that a full solution for the current code might look something like:

// startup.js

app.UseMvc(routeBuilder =>
{
  routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(100).Count();
  routeBuilder.MapODataServiceRoute("odata", "odata", containerBuilder =>
  {
    containerBuilder.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEdmModel), sp => GetEdmModel())
      .AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataBatchHandler), sp => new DefaultODataBatchHandler())
      .AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEnumerable<IODataRoutingConvention>), sp =>
        ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", routeBuilder));
    containerBuilder.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new CustomODataSerializerProvider(sp));
  });
});

// Other class
public class CustomODataSerializerProvider : DefaultODataSerializerProvider
{
  private AnnotatingEntitySerializer _annotatingEntitySerializer;

  public CustomODataSerializerProvider(IServiceProvider serviceProvider) : base(serviceProvider)
  {
    _annotatingEntitySerializer = new AnnotatingEntitySerializer(this);
  }

  public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
  {
    if (edmType.IsEntity())
    {
      return _annotatingEntitySerializer;
    }
    return base.GetEdmTypeSerializer(edmType);
  }
}

public class AnnotatingEntitySerializer : ODataResourceSerializer
{
  public AnnotatingEntitySerializer(ODataSerializerProvider serializerProvider)
    : base(serializerProvider)
  {
  }

  public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
  {
    var resource = base.CreateResource(selectExpandNode, resourceContext);
    var res = resourceContext.ResourceInstance as Resource;
    if (resource != null && res?.Score.HasValue == true)
    {
      resource.InstanceAnnotations.Add(new ODataInstanceAnnotation("search.score", new ODataPrimitiveValue(res.Score)));
    }
    return resource;
}

```

@GregSem
Do you have any solution for adding Custom ODataDeserializerProvider? Here is my code that is not working:
configureAction.AddService<ODataDeserializerProvider>(ServiceLifetime.Singleton, s => new JsonODataDeserializerProvider(app.ApplicationServices));

It was working on .Net

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NetTecture picture NetTecture  路  4Comments

davidmorissette picture davidmorissette  路  3Comments

christiannagel picture christiannagel  路  4Comments

ilya-chumakov picture ilya-chumakov  路  5Comments

joelmeaders picture joelmeaders  路  4Comments