Search code examples
c#asp.netasp.net-web-apiodata

ASP.NET WebAPI OData 406


I have an issue with getting a fairly simple OData WebAPI service to work. Outside of the metadata query on ~/ and ~/$metadata checking my own entity set returns a 406. When debugging the controller (see below) the GET request gets routed through, the db is queried and data is actually returned. However a 406 is still generated afterwards.

The expected response is a properly formatted JSON response string showing all lines of data when querying ~/Crops.

Note that some of this is still black magic to me so feel free to elaborate on any responses. Here's the wiring:

Global.asax

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.AddODataQueryFilter();
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Crop>("Crops");
        var model = builder.GetEdmModel();

        config.MapODataServiceRoute(
            routeName: "odata",
            routePrefix: null,
            model: model);
    }
}

Crop Model:

public class Crop
{
    [Key]
    public int CropId { get; set; }
    [Required]
    public string Name { get; set; }
    public int MinCost { get; set; }
    public int DefaultCost { get; set; }
    public int MaxCost { get; set; }
}

CropsController (Excerpt):

public class CropsController : ODataController
{
    private ParadiseDataContext db = new ParadiseDataContext();

    // GET: odata/Crops
    [EnableQuery]
    public IQueryable<Crop> GetCrops()
    {
        return db.Crops;
    }

Queries URLs plus results:

Home:

http://localhost:39086/
{
  "@odata.context":"http://localhost:39086/$metadata","value":[
    {
      "name":"Crops","kind":"EntitySet","url":"Crops"
    }
  ]
}

Querying Crops

http://localhost:39086/Crops
406 - Not Accepted (Empty Body)

Project file: https://www.dropbox.com/s/5k62xl8bdfbzgq7/ParadiseBayDataService.zip?dl=0 All of the binaries have been removed, all VSSO references have been removed. Nuget package configuration should restore dependencies.


Solution

  • I figured out what the issue was:

    Again the model (now full code)

    using System.Data;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Net;
    using System.Threading.Tasks;
    using System.Web.Http;
    using System.Web.Http.OData;
    using ParadiseBayDataService.Models;
    
    namespace ParadiseBayDataService.Controllers
    {
        [EnableQuery]
        public class CropsController : ODataController
    
        {
            private ParadiseDataContext db = new ParadiseDataContext();
    
            // GET: odata/Crops
            [EnableQuery]
            public IQueryable<Crop> GetCrops()
            {
                return db.Crops;
            }
    

    The thing to note here is the line:

    using System.Web.Http.OData;
    

    When I changed this to:

    using System.Web.OData;
    

    It works as expected. I did see a link that references the same thing. Just the answer to the question was more like "Use System.Web.OData" without much context. I got to this by going back to the basics following a guide. The one major difference between that working sample and what I had was this one line. The routing doesn't give you much to go on through debugging, the crux seemingly being in the "EnableQuery"