Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$Metadata with WebAPi OData Attribute Routing Not Working

I'm using OData Attribute Routing for an OData endpoint. Here is an example of what I have:

[ODataRoutePrefix("Profile")]
public class ProfileODataController : ODataController
{
    [ODataRoute]
    [EnableQuery]
    public IHttpActionResult Get()
    {
        var repo = new Repositories.ProfileRepository();

        return Ok(repo.GetProfiles());
    }

    [ODataRoute("({key})")]
    [EnableQuery]
    public IHttpActionResult Get([FromODataUri] string key)
    {
        var repo = new Repositories.ProfileRepository();

        var result = repo.GetProfiles().SingleOrDefault(x => x.Id== key);
        if (result == null) return NotFound();

        return Ok(result);
    }
}

Here is my set up:

config.MapODataServiceRoute("odata", "odata", ModelGenerator.GetEdmModel());

Here is my EdmModel Generation:

public static IEdmModel GenerateEdmModel()
{
    var builder = new ODataConventionModelBuilder();

    builder.EntitySet<Profile>("Profile").EntityType.HasKey(x => x.Id);

    return builder.GetEdmModel();
}

The urls /odata/Profile and /odata/Profile('someid') both work, but when I try to access the $metadata endpoint (/odata/$metadata#Profile), I get the following error:

{"Message":"No HTTP resource was found that matches the request URI 'http://****/odata/$metadata'.","MessageDetail":"No type was found that matches the controller named 'Metadata'."}

Do I need to create a controller/action for serving the metadata? If so, how is that action implemented?

like image 762
Nathan A Avatar asked Feb 12 '23 01:02

Nathan A


1 Answers

Turns out it had to do with my replacement of the IAssembliesResolver.

I had implemented a custom version to provide only the component assemblies that I had implemented controllers in. However, as the error said, it couldn't find a controller named MetadataController. Turns out, OData implements one: System.Web.OData.MetadataController, which provides for the $metadata keyword.

Since I had implemented my own IAssembliesResolver, the System.Web.OData assembly wasn't being included, and $metadata failed. Once I discovered this, and updated my assembly resolver to explicitly include the OData assembly, it now works as it should.

like image 125
Nathan A Avatar answered Feb 14 '23 16:02

Nathan A