WebAPI 和 ODataController 返回 406 Not Acceptable [英] WebAPI and ODataController return 406 Not Acceptable
问题描述
在将 OData 添加到我的项目之前,我的路由设置如下:
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
所有控制器都提供 Get、Put(动作名称为 Create)、Patch(动作名称为 Update)和 Delete.例如,客户端将这些不同的标准 url 用于 CustomerType 请求:
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";
然后我添加了一个与我的其他 Api 控制器具有相同操作名称的 OData 控制器.我还添加了一条新路线:
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()
);
到目前为止,我在客户端没有做任何更改.当我发送请求时,我收到 406 Not Available 错误.
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?
推荐答案
配置路由的顺序会产生影响.就我而言,我还有一些标准的 MVC 控制器和帮助页面.所以在 Global.asax
中:
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 }
);
}
作为奖励,这是我的 RouteConfig.cs
:
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 }
);
}
这必须按照确切顺序.我尝试移动调用,结果 MVC、Api 或 Odata 因 404 或 406 错误而损坏.
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.
所以我可以打电话:
localhost:xxx/-> 引导到帮助页面(主控制器、索引页面)
localhost:xxx/ -> leads to help pages (home controller, index page)
localhost:xxx/api/-> 指向 OData $metadata
localhost:xxx/api/ -> leads to the OData $metadata
localhost:xxx/api/Sites -> 导致我的 SitesController 的 Get 方法继承自 ODataController
localhost:xxx/api/Sites -> leads to the Get method of my SitesController inheriting from ODataController
localhost:xxx/api/Test -> 导致我的 TestController 的 Get 方法继承自 ApiController.
localhost:xxx/api/Test -> leads to the Get method of my TestController inheriting from ApiController.
这篇关于WebAPI 和 ODataController 返回 406 Not Acceptable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!