Part 04 – OData v4 in ASP.NET WebApi – Metadata Document

This is a series of blogs detailing my introduction to using OData v4 with C# and ASP.NET WebApi.

What is a Metadata Document

An OData Metadata Document shows a more detailed XML data model that describes the data and operations exposed by an OData service. All OData services must have metadata document. The Metadata Document URL must be the root URL of the service with $metadata appended.

Viewing the Metadata Document

Let’s look at the metadata document for the Trip Pin service. We do this by appending $metadata to the root service URL.

Issuing a GET request to$metadata we get the following XML response returned. I have collapsed allot of the elements to make it more readable.

My intention is not to go in depth but rather just point out some observations.

The XML document use the edmx namespace.

The Edmx element has a Version attribute set to 4.0 to represent the specification used.

The DataServices element can contain one or more Schema elements. In our example above we have one.

Within a Schema element we have a number of types. These can be:

  • Action
  • Annotations
  • Annotation
  • ComplexType
  • EntityContainer
  • EntityType
  • EnumType
  • Function
  • Term
  • TypeDefinition

The Name of each type must be unique across the schema.

At the bottom of the Schema element is an EntityContainer element. There can only be one and it is here that the entity sets, singletons, function and action imports are exposed by the service to be used by the clients. It shows similar information to what we saw in the Service Document in the previous blog.

If we expand the EntityContainer element we see the types exposed by the service.

Notice the EntityType shown. It corresponds to a type in the schema above it. Looking at the Airports element it has an EntityType of Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airport. This uses instances of Airport within the long namespace prefix. Let’s look at the Airport schema.

The Airport type has four fields (Properties). IcaoCode is defined as a Key and therefore each value is unique and can be used for single instance lookups. It is declared as a String type and must not contain NULL values. You can define keys on multiple fields if required.

String is what we call a primitive type meaning, it’s defined by the standard and is available out of the box,

Looking at the Location property, its type points to AirportLocation which appears in the schema as a ComplexType.

ComplexTypes are types we can define which can contain one or more properties. They can be used by more than one other type.

A better example is the City type below which shows three properties.

Lastly notice there are some Actions and Functions defined.

Actions and Functions are a way to add server-side behaviours that are not easily defined as standard CRUD operations on entities. The difference between actions and functions is that actions can have side effects, and functions do not. What does that mean? Think of functions for reading data and actions for writing data. This means functions can read anything and not be related to a single entity or collection. Both actions and functions can return data.

There are many more elements and attributes that can exist which are explained in the standards document.

In the next blog we will look at querying OData.