Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding arbitrary data to OData metadata in WebAPI?

I have a simple WebAPI2 service that uses OData (System.Web.Http.OData, 5.1.0.0). Users can hit /odata/$metadata to get the available entities and properties. I'm looking for a way to extend this metadata with additional information, such as adding a "display name" value to a property.

I found information about "annotations" that sounds like it is what I want, but I cannot find anything explanining how to use this in my scenario or if it is even possible. I was trying to do something like the following:

model.SetAnnotationValue(((IEdmEntityType)m.FindType("My.Thing")).FindProperty("SomeProperty"),
       namespaceName:"MyNamespace",
       localName: "SomeLocalName",
       value: "THINGS");

The type/property names are correct and the call succeeds, but the OData EDMX document does not contain this annotation. Is there some way to expose these annotations or otherwise do what I want?

Update:
Still at it. I've been looking at ODataMediaTypeFormatters as a possible way to handle this. There is an ASP.NET sample project that shows how to add instance annotations to entities. Close, but not exactly what I want, so now I'm trying to find a way to extend whatever generates the metadata document in a similar way.

like image 635
kenchilada Avatar asked Mar 05 '14 19:03

kenchilada


1 Answers

I figured out a way to do this. The code below adds a custom namespace prefix "myns" and then adds an annotation on a model property:

const string namespaceName = "http://my.org/schema";
var type = "My.Domain.Person";
const string localName = "MyCustomAttribute";

// this registers a "myns" namespace on the model
model.SetNamespacePrefixMappings(new [] { new KeyValuePair<string, string>("myns", namespaceName), });

// set a simple string as the value of the "MyCustomAttribute" annotation on the "RevisionDate" property
var stringType = EdmCoreModel.Instance.GetString(true);
var value = new EdmStringConstant(stringType, "BUTTONS!!!");
m.SetAnnotationValue(((IEdmEntityType) m.FindType(type)).FindProperty("RevisionDate"),
                        namespaceName, localName, value);

Requesting the OData metadata document should give you something like this:

<edmx:Edmx Version="1.0">
    <edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
        <Schema Namespace="My.Domain">
            <EntityType Name="Person">
                <Key><PropertyRef Name="PersonId"/></Key>
                <Property Name="RevisionDate" Type="Edm.Int32" Nullable="false" myns:MyCustomAttribute="BUTTONS!!!"/>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>
like image 86
kenchilada Avatar answered Oct 30 '22 15:10

kenchilada