3

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.

AlexR
  • 305
  • 1
  • 2
  • 10
  • 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 Jan 18 '16 at 04:30
  • Possible duplicate of [WebAPI and ODataController return 406 Not Available](http://stackoverflow.com/questions/26676879/webapi-and-odatacontroller-return-406-not-available) – Orif Khodjaev Jan 18 '16 at 04:48
  • and some more info on the 406 http://stackoverflow.com/questions/14251851/what-is-406-not-acceptable-response-in-http – Marvin Smit Jan 18 '16 at 09:07
  • 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 Jan 18 '16 at 11:59
  • 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 Jan 19 '16 at 01:57
  • What's the best way to share the repo? I'm on VSO so I can't publicly share, there's no sensitive stuff in there so I don't mind packing it all up. I removed the odata prefix from my code I also removed all of that stuff from my request. It didn't make any difference regardless – AlexR Jan 19 '16 at 15:02
  • I added the project/solution files. – AlexR Jan 19 '16 at 15:13

1 Answers1

0

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"

AlexR
  • 305
  • 1
  • 2
  • 10
  • Glad you fixed this but it's not my problem, I am using System.Web.OData; everywhere. :( – Worthy7 Jan 14 '17 at 08:04
  • I received a 406 when implementing a custom action. The object I was returning to the client from my ODataController was not the same as the Type I specified in my action's .Returns when creating the model. – Scope Creep Feb 03 '17 at 17:44