我目前正在使用ASP.NET MVC 4 Web API中的OData端点进行试验。我喜欢这个概念,并尝试在我们的项目中提出有效的方法。 我有一个问题如下:我们有一个能够返回IQueryable并将实体名称作为输入的服务:
public IQueryable GetAll(string entityName);
在标准Web API(与OData控制器相对)中,我可以创建一个通用控制器,可以以/ api / entities / {entityName}的形式调用并返回IQueryable。 对于OData控制器,我执行以下特定于实体的步骤:
我想使用通用服务,尽可能避免实体特定的实现。如果服务可以返回实体列表和相应类型,则可以轻松地自动完成第一步。 这留下了第2步,因为到目前为止我需要为每个实体创建一个特定的控制器。我还想避免这种情况,并创建一个使用通用服务的通用控制器。
任何人都可以通过影响OData路由推荐解决方案吗?
答案 0 :(得分:11)
您可以创建自定义路由约定,无论实体集是什么,都会选择相同的控制器。例如,
public class CustomControllerRoutingConvention : IODataRoutingConvention
{
public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
{
return null;
}
public string SelectController(ODataPath odataPath, HttpRequestMessage request)
{
return "SomeFixedContrllerNameWithoutTheControllerSuffix";
}
}
您可以使用以下代码
注册该路由约定IList<IODataRoutingConvention> routingConventions = ODataRoutingConventions.CreateDefault();
routingConventions.Insert(0, new CustomControllerRoutingConvention());
config.Routes.MapODataRoute("OData", "odata", builder.GetEdmModel(), new DefaultODataPathHandler(), routingConventions);
答案 1 :(得分:6)
我遇到了同样的问题,最后编写了自定义IHttpControllerSelector
而不是IODataRoutingConvention
。如果您的通用控制器不需要泛型,IODataRoutingConvention
看起来是个不错的选择。但由于IODataRoutingConvention.SelectController()
只返回一个字符串,我看不出它如何用于实例化具有泛型类型参数的控制器。
我认为这个问题需要一个好的,通用的开源解决方案 - 所以我创建了一个:http://entityrepository.codeplex.com。现在是预发布,但我目前正在做很多工作。我认为除了选择正确的控制器之外还有更多内容,为共享控制器定义了一般模式,默认情况下,Web API OData需要强类型和强命名的导航属性,这使得创建可重用的实现变得具有挑战性。 / p>