3
votes

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.

1
I query it in the most basic way (haven't gotten to anything beyond this) querying with ~/Crops gets me to my break point in the GetCrops part of the code. I validated that the db.Crops actually returns data through the Result Viewer. - AlexR
and some more info on the 406 stackoverflow.com/questions/14251851/… - Marvin Smit
Neither one of the threads above seem to apply to my situation: the first seems to refer to some missing routing. I think it's using a different version of OData since the settings indicated in the answer are not available. Modifying the code with the other items gave no different results. Marvin's thread indicates that the client doesn't except application/json: I created the following accept header on fiddler to test: Accept: text/html,application/xhtml+xml,application/xml,application/json,text/plain;q=0.9;image/webp,/;q=0.8; with the same result - AlexR
Everything you listed looks good to me except that the odata route prefix "odata" you mentioned, but not used in your code. However, it's not the root reason. Would you please share me a repo project ( a console application is ok)? - Sam Xu

1 Answers

0
votes

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"