我在同一个项目中使用WebApi 2控制器与单个OData控制器并排工作。尝试设置所需的路由配置:
当我尝试将 / api 路线映射到OData控制器时,如下所示:
class WebApiConfig
{
public static void Register(HttpConfiguration configuration)
{
configuration.Routes.MapHttpRoute("API Default", "api/{action}/{id}",
new { controller = "ApiOdata", id = RouteParameter.Optional });
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Organization>("Organizations");
configuration.Routes.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "Api",
model: builder.GetEdmModel());
}
}
所有方法调用都适用于Web Api和OData控制器,但 / api / $ metadata 等请求不起作用。
当我删除“API Default”路径时 - 对OData控制器方法的请求 / api / Organizations 停止工作(返回404),但 / api / $ metadata 开始
404详细错误消息:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:53576/api/Organizations'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'Organizations'.
</MessageDetail>
</Error>
将所有OData调用映射到单个控制器操作的正确方法是什么?
答案 0 :(得分:0)
最后结束了自定义路由约定。为它添加了类:
public class CustomControllerRoutingConvention : IODataRoutingConvention
{
public string SelectAction(System.Web.OData.Routing.ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
{
if (odataPath.PathTemplate.StartsWith("~/entityset")
|| odataPath.PathTemplate.StartsWith("~/unboundfunction"))
{
return odataPath.Segments[0].Identifier;
}
// Not a match.
return null;
}
public string SelectController(System.Web.OData.Routing.ODataPath odataPath, HttpRequestMessage request)
{
if (!odataPath.PathTemplate.Contains("$metadata"))
{
if (odataPath.PathTemplate != "~")
{
return "ApiOdata";
}
}
return null;
}
}
并在WebApiConfig.cs的Register方法中使用它:
public static void Register(HttpConfiguration configuration)
{
...
IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault();
routingConventions.Insert(0, new CustomControllerRoutingConvention());
configuration.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "Api",
pathHandler: new DefaultODataPathHandler(),
routingConventions: routingConventions,
model: builder.GetEdmModel());
}
它不是完美的解决方案,不会为每个OData请求提供服务(只有元数据,实体集和未绑定的功能,例如&#34; api / Organizations&#34;)但它足够用于处理像o.js和Simple.Odata.Client这样的客户端。 此外,它允许避免控制器弄乱和膨胀我的项目。