Skip to content

Instantly share code, notes, and snippets.

@rschiefer
Created October 18, 2019 13:32
Show Gist options
  • Save rschiefer/b3abdd3bc4d9eb3fb667e18a5b423bd5 to your computer and use it in GitHub Desktop.
Save rschiefer/b3abdd3bc4d9eb3fb667e18a5b423bd5 to your computer and use it in GitHub Desktop.
ASP.NET Core WebAPI ODATA - Add Custom Metadata Annotation to Feed
public class CustomSerializerProvider : DefaultODataSerializerProvider
{
public CustomSerializerProvider(IServiceProvider rootContainer)
: base(rootContainer)
{
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
{
if (edmType.IsCollection() && edmType.AsCollection().ElementType().IsEntity())
{
return new CustomFeedSerializer(this);
}
else if (edmType.IsEntity())
{
return new CustomEntrySerializer(this);
}
return base.GetEdmTypeSerializer(edmType);
}
}
public class CustomFeedSerializer : ODataResourceSetSerializer
{
public CustomFeedSerializer(ODataSerializerProvider serializerProvider)
: base(serializerProvider)
{
}
public override ODataResourceSet CreateResourceSet(IEnumerable feedInstance, IEdmCollectionTypeReference feedType,
ODataSerializerContext writeContext)
{
try
{
ODataResourceSet feed = base.CreateResourceSet(feedInstance, feedType, writeContext);
Extensions.AddInstanceAnnotationsFromHeader(feed, writeContext.Request);
return feed;
} catch
{
return base.CreateResourceSet(feedInstance, feedType, writeContext);
}
}
}
public class CustomEntrySerializer : ODataResourceSerializer
{
public CustomEntrySerializer(ODataSerializerProvider serializerProvider)
: base(serializerProvider)
{
}
public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext entityContext)
{
ODataResource entry = base.CreateResource(selectExpandNode, entityContext);
Extensions.AddInstanceAnnotationsFromHeader(entry, entityContext.Request);
return entry;
}
}
public static class Extensions
{
public static void AddInstanceAnnotationsFromHeader(ODataItem resource, Microsoft.AspNetCore.Http.HttpRequest request)
{
var prefix = "odataAnnotation_";
foreach (var header in request.HttpContext.Response.Headers.Where(x => x.Key.StartsWith(prefix)))
{
var key = header.Key.Substring(prefix.Length);
var value = new ODataPrimitiveValue(header.Value.FirstOrDefault());
var annotation = new ODataInstanceAnnotation(key, value);
if ((resource as ODataResourceBase) != null)
{
(resource as ODataResourceBase)?.InstanceAnnotations.Add(annotation);
}
if ((resource as ODataResourceSetBase) != null)
{
(resource as ODataResourceSetBase)?.InstanceAnnotations.Add(annotation);
}
}
}
}
//...
routeBuilder.MapODataServiceRoute("odata", "odata", builder => builder
.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => this.funcEdmModel())
.AddService<ODataSerializerProvider, CustomSerializerProvider>(Microsoft.OData.ServiceLifetime.Singleton)
.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, sp =>
ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", routeBuilder))
);
//...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment