MartynJones87
MartynJones87

Reputation: 457

Programmatically Generate Asp Net Web Api OData Route Metadata

Is there are a way to programmatically generate the /$metadata response returned from an ASP.Net Web Api OData controller route in a way that can be serialized to XML?

The reason I want to do this is that I'm using breeze to access the Web API using the OData adapter and would like to pre-load the Breeze MetadataStore with the metadata, like in this http://breeze.github.io/doc-js/metadata-load-from-script.htmlexample.

But this example does not seem to work with the OData adapter as it uses different metadata.

Upvotes: 1

Views: 1137

Answers (2)

lencharest
lencharest

Reputation: 2935

If I understand your question, you are trying to simulate GET /$metadata on the server so you can store the results in a file. In ASP.NET OData, $metadata is represented by an object that implements IEdmModel (e.g., the result of calling ODataModelBuilder.GetEdmModel). The problem then becomes how to serialize that model to XML.

The following helper will write service metadata to the given stream. For the model and config parameters, you should pass the same objects you used for your service configuration.

public class MetadataHelper
{
    public static Task WriteMetadataAsync(Stream stream, IEdmModel model, HttpConfiguration config, string odataRouteName)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, "/$metadata");

        request.ODataProperties().Model = model;
        request.ODataProperties().RouteName = odataRouteName;
        request.SetConfiguration(config);

        var payloadKinds = new List<ODataPayloadKind> { ODataPayloadKind.MetadataDocument };
        var xmlMediaType = new MediaTypeHeaderValue("application/xml");
        var formatter = new ODataMediaTypeFormatter(payloadKinds).GetPerRequestFormatterInstance(model.GetType(), request, xmlMediaType);
        var content = new StringContent(String.Empty);

        content.Headers.ContentType = xmlMediaType;

        return formatter.WriteToStreamAsync(model.GetType(), model, stream, content, null);
    }
}

Upvotes: 2

Steve Schmitt
Steve Schmitt

Reputation: 3209

True, the OData metadata is handled correctly by Breeze only when reading an OData response; the MetadataStore doesn't import/export it directly.

I think the easiest way to handle this is to create a separate bit of client-side code that will

  1. Create an EntityManager that will
  2. Fetch the metadata from the OData server
  3. Export the metadata from the MetadataStore
  4. Log the metadata so you can capture it and store it in a file

Not elegant, but it gets the job done.

Some future version of breeze.server.net will do the OData-to-Breeze metadata conversion on the server, so we won't have this problem.

Upvotes: 0

Related Questions