Open tomfrenzel opened 1 year ago
This seems like a feature gap.
In the meantime, you can try a workaround using the Prefer: include-annotations
header to specify which annotations should be returned: http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_Preferenceincludeannotationsodatainc
For example, Prefer: include-annotations=*
to include all annotations.
Does that work for you?
Hi @habbes!
Unfortunately, the header does not help. I tried extending the Product model with the following property and expected to get the annotation returned when the header is present.
[NotMapped]
public ODataInstanceAnnotation Annotation => new("ns.annotations", new ODataCollectionValue()
{
Items = new List<ODataUntypedValue>()
{
new()
{
RawValue = @"{""Name"": ""Test""}",
TypeAnnotation = new ODataTypeAnnotation(typeof(Customer).FullName)
}
},
TypeName = $"Collection({typeof(ODataUntypedValue).FullName})"
});
That was not the case. To get annotations working in general, I used the following custom code:
public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
{
var resource = base.CreateResource(selectExpandNode, resourceContext);
if (resourceContext != null &&
resourceContext.ResourceInstance != null &&
annotationsRequested(resourceContext)
)
{
setAnnotations(resourceContext.ResourceInstance, resource);
}
return resource;
}
private bool annotationsRequested(ResourceContext resourceContext)
{
return resourceContext.SerializerContext.Request.Headers.TryGetValue("Prefer", out var headerValues) &&
headerValues.Any(s => s.Contains("odata.include-annotations"));
}
private void setAnnotations(object resourceInstance, ODataResource resource)
{
foreach (var annotationProp in getAnnotationProperties(resourceInstance))
{
var annotationValue = annotationProp.GetValue(resourceInstance) as ODataInstanceAnnotation;
if (annotationValue != null)
{
if (resource.InstanceAnnotations == null)
{
resource.InstanceAnnotations = new List<ODataInstanceAnnotation>();
}
resource.InstanceAnnotations.Add(annotationValue);
}
}
}
Is there currently even a way to make use of annotations out of the box? Because I couldn't get it working.
Assemblies affected ASP.NET Core OData 8.0.12
Describe the bug When specifying an instance annotation inside the
select
of a GET request, the user receives an error that this is not supported. The OData specification on the other hand states that it should be possible.Reproduce steps This behavior can be reproduced simply by specifying any annotation inside the
select
of a request.Data Model
Request/Response Request:
GET http://localhost:64771/v1/Customers?select=@ns.annotation
Response:Expected behavior If the annotation exists, it should be included in the response
Additional context Although this sample project does not make use of annotations it shows that it is generally not possible to receive annotations in a selected list. I first noted the Bug when annotations of entities inside a list would not show up in the response body if only specific properties got requested by specifying them inside the
select
. After reading through the OData specification, I tried to also select the annotation but this gave me the error above.