使用以下查询的基本Get方法构建ODataController:
http://localhost:8080/api/Bases
很简单:
[EnableQuery]
public IHttpActionResult Get()
{
return Ok(new List<Base>());
}
在相同的样式中,我正在尝试实现"cast"路由("~/entityset/cast"),该路由在OData V4 convention part 4.9中定义,但这完全没有记录 . 所以我挖了一些source code并发现对于以下网址:
http://localhost:8080/api/Bases/MyNamespace.DerivedA
我可以在同一个控制器中定义以下方法:
[EnableQuery]
public IHttpActionResult GetFromDerivedA()
{
return Ok(new List<DerivedA>());
}
哪个有效,但我有十几种从 Base
继承的类型 . 而不是为每个派生类型声明一个方法,有没有办法可以使用类似的东西:
[EnableQuery]
public IHttpActionResult GetFrom<T>()
where T : Base
{
return Ok(new List<T>());
}
我正在使用:
-
Microsoft.AspNet.WebApi 5.2.3
-
Microsoft.OData 6.13.0
-
Microsoft.AspNet.OData 5.6.0
更新
我可以创建a new RoutingConvention并使覆盖的SelectAction返回我的泛型方法,但似乎我不得不忘记泛型方法方法:
“无法在控制器'MyProject.Controllers.BasesController'上调用动作方法'System.Web.Http.IHttpActionResult GetFrom [T]()',因为动作方法是一种通用方法 . ”
那怎么样,这可能吗?
[EnableQuery]
public IHttpActionResult GetFrom(Type derivedType)
{
//snip!
}
如果没有,还有其他想法吗?
1 回答
这是我通过一些反思来实现这一目标的方法 . 这是相当长的路,但最终的控制器方法非常简单,值得 .
首先,创建一个新的RoutingConvention . 请注意,我们将把所有强制转换请求转发给名为
GetFrom
的方法:接下来,将其添加到OData配置:
现在,因为默认模型 Binders 不会从路径数据字典中读取任意参数名称,所以我们需要a custom model binder用于路径数据:
最后,在控制器中添加所需的方法 . 请注意它是多么微不足道:
由于我'm using Entity Framework and I can'使用
GetType()
,我必须使用另一个反射技巧来调用带有Type
实例的OfType<T>()
. 如果你正在处理内存中的实体,只需废弃最后一部分并使用普通的: