If user wants to implement his own metadata controller, it will be hard for him to get the service document.
1. There is no virtual method in ODataMetadataController to let user to override EdmModel
2. If user implements controller from ApiController, it's hard to build service document because we has no public API to get entity set url.
Here is the product code:
public HttpResponseMessage GetServiceDocument()
{
IEdmModel model;
MediaTypeFormatter odataFormatter = GetFormatter(typeof(ODataWorkspace), out model);
ODataWorkspace workspace = new ODataWorkspace();
IEdmEntityContainer container = model.EntityContainers().Single();
IEnumerable<IEdmEntitySet> entitysets = container.EntitySets();
IEnumerable<ODataResourceCollectionInfo> collections = entitysets.Select(e => GetODataResourceCollectionInfo(model.GetEntitySetUrl(e).ToString(), e.Name));
workspace.Collections = collections;
// This controller requires and supports only the OData formatter.
return Request.CreateResponse(HttpStatusCode.OK, workspace, odataFormatter);
}
private static ODataResourceCollectionInfo GetODataResourceCollectionInfo(string url, string name)
{
ODataResourceCollectionInfo info = new ODataResourceCollectionInfo
{
Url = new Uri(url, UriKind.Relative)
};
info.SetAnnotation<AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata { Title = name });
return info;
}
The GetEntitySetUrl extension method is internal.
Comments: You need to write your own ApiController and you can call the following code yourself to replace the internal extension method. EntitySetUrlAnnotation annotation = model.GetAnnotationValue<EntitySetUrlAnnotation>(entitySet); if (annotation == null) { return entitySet.Name; } else { return annotation.Url; }
1. There is no virtual method in ODataMetadataController to let user to override EdmModel
2. If user implements controller from ApiController, it's hard to build service document because we has no public API to get entity set url.
Here is the product code:
public HttpResponseMessage GetServiceDocument()
{
IEdmModel model;
MediaTypeFormatter odataFormatter = GetFormatter(typeof(ODataWorkspace), out model);
ODataWorkspace workspace = new ODataWorkspace();
IEdmEntityContainer container = model.EntityContainers().Single();
IEnumerable<IEdmEntitySet> entitysets = container.EntitySets();
IEnumerable<ODataResourceCollectionInfo> collections = entitysets.Select(e => GetODataResourceCollectionInfo(model.GetEntitySetUrl(e).ToString(), e.Name));
workspace.Collections = collections;
// This controller requires and supports only the OData formatter.
return Request.CreateResponse(HttpStatusCode.OK, workspace, odataFormatter);
}
private static ODataResourceCollectionInfo GetODataResourceCollectionInfo(string url, string name)
{
ODataResourceCollectionInfo info = new ODataResourceCollectionInfo
{
Url = new Uri(url, UriKind.Relative)
};
info.SetAnnotation<AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata { Title = name });
return info;
}
The GetEntitySetUrl extension method is internal.
Comments: You need to write your own ApiController and you can call the following code yourself to replace the internal extension method. EntitySetUrlAnnotation annotation = model.GetAnnotationValue<EntitySetUrlAnnotation>(entitySet); if (annotation == null) { return entitySet.Name; } else { return annotation.Url; }