August 12th, 2019

Customize Control Information for full metadata requests in odata.net

Background

OData supports three metadata levels for the JSON format, namely –

  1. No Metadata
  2. Minimal Metadata
  3. Full Metadata

No Metadata as the name suggests does not include control information other than nextLink and count. Minimal metadata responses usually include context, etag, deltalink etc. whereas full metadata responses contain all the control information like navigationLink, assciationLink, readLink, mediaReadLink etc.

ODataMetadataSelector

With odata.net >=7.6.1, it will be possible to customize what metadata gets written out. A new class, ODataMetadataSelector is introduced which exposes methods that can be overridden to add or remove control information related to the navigation properties, stream properties, and operations.

 

public virtual IEnumerable<IEdmOperation> SelectBindableOperations(IEdmStructuredType type, IEnumerable<IEdmOperation> bindableOperations)
{
    // Select bindable operations
    return bindableOperations;
}

public virtual IEnumerable<IEdmNavigationProperty> SelectNavigationProperties(IEdmStructuredType type, IEnumerable<IEdmNavigationProperty> navigationProperties)
{
   // Select the navigation properties from the type
   return navigationProperties;
}

public virtual IEnumerable<IEdmStructuralProperty> SelectStreamProperties(IEdmStructuredType type, IEnumerable<IEdmStructuralProperty> selectedStreamProperties)
{
   // Select the streamProperties from the type
   return selectedStreamProperties;
}

The instance of this class can be set on ODataMessageWriterSettings’s property, MetadataSelector. Since ODataMessageWriterSettings can be dependency injected, you can also use dependency injection for ODataMetadataSelector by injecting a custom ODataMessageWriterSettings.

Since this will get called for every resource being requested, it is highly recommended to cache the results if possible.

Usage Example

You can choose to annotate properties of types for which you don’t want to write out the metadata. This sample here will omit control information for all such navigation properties. You can also have arbitrary criteria to select the metadata such as omitting all actions.

    public class SampleMetadataSelector : ODataMetadataSelector
    {
        private IEdmModel model;

        private IDictionary<IEdmVocabularyAnnotatable, bool> annotationCache;
        
        public SampleMetadataSelector(IEdmModel model, IDictionary<IEdmVocabularyAnnotatable, bool> cache)
        {
            this.model = model;
            this.annotationCache = isHiddenDictionary;
        }

        public override IEnumerable<IEdmNavigationProperty> SelectNavigationProperties(IEdmStructuredType type, IEnumerable<IEdmNavigationProperty> navigationProperties)
        {
            return navigationProperties.Where(s =>
                {
                    if (!isHiddenCache.ContainsKey(s))
                    {
                        IEdmVocabularyAnnotation annotation = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(s, "AnnotationName").FirstOrDefault();
                        annotationCache[s] = annotation == null;
                    }

                    return annotationCache[s];
                }
            );
        }

        public override  IEnumerable<IEdmOperation> SelectBindableOperations(IEdmStructuredType type, IEnumerable<IEdmOperation> bindableOperations)
        {
            //Omit all actions
            return bindableOperations.Where(f => f.SchemaElementKind != EdmSchemaElementKind.Action);
        }
    }

 

Category
OData

Author

Kanish is a Software engineer at Microsoft.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Jain, Vikram

    Can you please suggest what is advantage of using 7.6 in compare with 6.15 library. We are using 6.15 library and facing some performance issue.
    If we migrate to latest library , will we get performance advantage?