Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

c# - WebAPI and ODataController return 406 Not Acceptable

Before adding OData to my project, my routes where set up like this:

       config.Routes.MapHttpRoute(
            name: "ApiById",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^[0-9]+$" },
            handler: sessionHandler
        );

        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { action = "Get" },
            constraints: null,
            handler: sessionHandler
        );

        config.Routes.MapHttpRoute(
            name: "ApiByIdAction",
            routeTemplate: "api/{controller}/{id}/{action}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^[0-9]+$" },
            handler: sessionHandler

All controllers provide Get, Put (action name is Create), Patch (action name is Update) and Delete. As an example, the client uses these various standard url's for the CustomerType requests:

string getUrl =  "api/CustomerType/{0}";
string findUrl = "api/CustomerType/Find?param={0}";
string createUrl = "api/CustomerType/Create";
string updateUrl = "api/CustomerType/Update";
string deleteUrl = "api/CustomerType/{0}/Delete";

Then I added an OData controller with the same action names as my other Api controllers. I also added a new route:

        ODataConfig odataConfig = new ODataConfig();

        config.MapODataServiceRoute(
            routeName: "ODataRoute",
            routePrefix: null,
            model: odataConfig.GetEdmModel()
        );

So far I changed nothing on the client side. When I send a request, I get a 406 Not Available error.

Are the routes getting mixed up? How can I solve this?

question from:https://stackoverflow.com/questions/26676879/webapi-and-odatacontroller-return-406-not-acceptable

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The order in which the routes are configured has an impact. In my case, I also have some standard MVC controllers and help pages. So in Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(config =>
    {
        ODataConfig.Register(config); //this has to be before WebApi
        WebApiConfig.Register(config); 

    });
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

The filter and routeTable parts weren't there when I started my project and are needed.

ODataConfig.cs:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes(); //This has to be called before the following OData mapping, so also before WebApi mapping

    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

    builder.EntitySet<Site>("Sites");
    //Moar!

    config.MapODataServiceRoute("ODataRoute", "api", builder.GetEdmModel());
}

WebApiConfig.cs:

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute( //MapHTTPRoute for controllers inheriting ApiController
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
    );
}

And as a bonus, here's my RouteConfig.cs:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute( //MapRoute for controllers inheriting from standard Controller
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

This has to be in that EXACT ORDER. I tried moving the calls around and ended up with either MVC, Api or Odata broken with 404 or 406 errors.

So I can call:

localhost:xxx/ -> leads to help pages (home controller, index page)

localhost:xxx/api/ -> leads to the OData $metadata

localhost:xxx/api/Sites -> leads to the Get method of my SitesController inheriting from ODataController

localhost:xxx/api/Test -> leads to the Get method of my TestController inheriting from ApiController.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...