So i am building a service that has to be consumed through OData and i am having a really difficult time figuring how to add custom formatters to it. I need my OData serializer to ignore null values when serializing data. I have created these 2 to achieve that :
public class SmartODataSerializerProvider : DefaultODataSerializerProvider
{
private readonly SmartODataEntityTypeSerializer _entityTypeSerializer;
public SmartODataSerializerProvider(IServiceProvider rootContainer)
: base(rootContainer)
{
_entityTypeSerializer = new SmartODataEntityTypeSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(Microsoft.OData.Edm.IEdmTypeReference edmType)
{
// Support for Entity types AND Complex types
if (edmType.Definition.TypeKind == EdmTypeKind.Entity || edmType.Definition.TypeKind == EdmTypeKind.Complex)
return _entityTypeSerializer;
else
return base.GetEdmTypeSerializer(edmType);
}
}
And
public class SmartODataEntityTypeSerializer : ODataResourceSerializer
{
public SmartODataEntityTypeSerializer(ODataSerializerProvider provider)
: base(provider) { }
/// <summary>
/// Only return properties that are not null
/// </summary>
/// <param name="structuralProperty">The EDM structural property being written.</param>
/// <param name="resourceContext">The context for the entity instance being written.</param>
/// <returns>The property be written by the serilizer, a null response will effectively skip this property.</returns>
public override Microsoft.OData.ODataProperty CreateStructuralProperty(Microsoft.OData.Edm.IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
{
var property = base.CreateStructuralProperty(structuralProperty, resourceContext);
return property.Value != null ? property : null;
}
}
These were provided on another stack overflow question. However, the issue arises when i try to use this serializer. I already have an odata endpoint that's working (it just serializes everything with null) and when i apply the following configuration to it i keep getting '404 Not Found' on the same EP that works without it.
app.UseEndpoints(endpoints =>
{
endpoints.MapODataRoute("odata", "odata", a =>
{
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEdmModel), sp => GetEdmModel(app.ApplicationServices));
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new SmartODataSerializerProvider(sp));
});
endpoints.EnableDependencyInjection();
//endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));
endpoints.MapControllers();
});
This is the endpoints settings. I commented out the line that makes it work but without custom formatters. Here's the IEdmModel function used in the setup :
private static IEdmModel GetEdmModel(IServiceProvider services)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(services);
builder.Namespace = "RS";
builder.EntitySet<PropertyIndexODataModel>("Properties");
builder.EntitySet<ReportResultModel>("Reports");
var function = builder.EntityType<ReportResultModel>().Collection.Function("Generate");
function.Parameter<int>("listId");
function.CollectionParameter<string>("functionsToRun");
function.ReturnsCollectionFromEntitySet<ReportResultModel>("Reports");
return builder.GetEdmModel();
}
So when i apply this odataroute i keep getting the 404. When i remove it and go back to 'endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));' it works without problems.
This seems like a very trivial thing but i searched everywhere and i still couldn't get it to work. I am using OData 7.4 and netcore 3.1. Thanks in advance!