我尝试在VS2013中抽象自动生成的ODataController类,因为代码在不同的控制器上看起来是相同的,除了POCO的名称,所以,我做了以下操作:
public abstract class ODataControllerBase<T,DB> : ODataController
where T : class, IIdentifiable, new()
where DB : DbContext, new()
{
protected DB _DataContext;
public ODataControllerBase() : base()
{
_DataContext = new DB();
}
// only one function shown for brevity
[Queryable]
public SingleResult<T> GetEntity([FromODataUri] int key)
{
return SingleResult.Create(_DataContext.Set<T>().Where(Entity => Entity.Id.Equals(key)));
}
}IIdentifiable是一个强制T参数具有可读/可写Id整数属性的接口。
实现如下所示(POCOs和DataContexts应该已经创建好了)
public class MyObjectsController : ODataControllerBase<MyObject,MyDbContext>
{
public MyObjectsController() : base()
{
}
// That's it - done because all the repetitive code has been abstracted.
}现在,我的WebApiConfig的Register函数只包含以下内容:
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<MyObject>("MyObjects");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
}我运行了这个项目,http://localhost:10000/odata/MyObjects,我得到了响应:
<m:error>
<m:code/>
<m:message xml:lang="en-US">No HTTP resource was found that
matches the request URI `http://localhost:10000/odata/MyObjects.`
</m:message>
<m:innererror>
<m:message>No routing convention was found to select an action
for the OData path with template '~/entityset'.
</m:message>
<m:type/>
<m:stacktrace/>
</m:innererror>
</m:error>遗漏了什么?我应该删除什么?这是不是我们不能做的事情,也就是说,我们真的需要直接继承ODataController而不需要中间父类吗?
发布于 2017-03-12 05:21:22
在我们的一个项目中,我们还使用了一个通用的ODataController基类,其中我们实际使用GetEntity来检索单个实体,使用GetEntitySet来检索实体列表。
根据您提供的URL和产生的错误消息,ODATA框架无法找到~/entityset的ODataAction。由于您已经给出了http://localhost:10000/odata/MyObjects作为示例,所讨论的操作不能是public SingleResult<T> GetEntity([FromODataUri] int key),因为这只对应于像这样的http://localhost:10000/odata/MyObjects(42)这样的查询。
我们的泛型控制器代码如下所示:
public abstract class OdataControllerBase<T> : ODataController
where T : class, IIdentifiable, new()
{
protected OdataControllerBase(/* ... */)
: base()
{
// ...
}
public virtual IHttpActionResult GetEntity([FromODataUri] long key, ODataQueryOptions<T> queryOptions)
{
// ...
return Ok(default(T));
}
public virtual async Task<IHttpActionResult> GetEntitySet(ODataQueryOptions<T> queryOptions)
{
// ...
return Ok<IEnumerable<T>>(default(List<T>));
}
public virtual IHttpActionResult Put([FromODataUri] long key, T modifiedEntity)
{
// ...
return Updated(default(T));
}
public virtual IHttpActionResult Post(T entityToBeCreated)
{
// ...
return Created(default(T));
}
[AcceptVerbs(HTTP_METHOD_PATCH, HTTP_METHOD_MERGE)]
public virtual IHttpActionResult Patch([FromODataUri] long key, Delta<T> delta)
{
// ...
return Updated(default(T));
}
public virtual IHttpActionResult Delete([FromODataUri] long key)
{
// ...
return Updated(default(T));
}
}然后,特定控制器的代码如下所示:
public partial class KeyNameValuesController : OdataControllerBase<T>
{
public KeyNameValuesController(/* ... */)
: base()
{
// there is nothing to be done here
}
}然而,我们发现这两个Get方法(对于单个结果和可枚举结果)实际上都必须以Get开头。首先,我们尝试了List而不是GetEntitySet,但这并不起作用,因为框架随后期望List操作的POST )。
实际上,您可以通过提供Routing and Action Selection in ASP.NET Web API中描述的自定义IHttpActionSelector来验证和诊断解析过程(查看ASP.NET WEB API 2: HTTP Message Lifecycle可能也是值得的)。
因此,实际上可以像您最初在示例中尝试的那样使用GetEntity作为方法名,并且不需要将其重命名为simple Get。此外,不需要对ODATA配置进行任何修改。
发布于 2015-03-13 00:18:01
为了确定要调用的操作,框架使用路由表。Web API的Visual Studio项目模板创建默认路由:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);按操作名称路由
对于默认的路由选择模板,Web API使用HTTP方法来选择操作。但是,您也可以在URI中包含操作名称的情况下创建路由:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);我将config配置如下:
config.Routes.MapHttpRoute(
name: "GetMessage",
routeTemplate: "api/{controller}/{action}/{quoteName}",
defaults: new { quoteName = RouterParameters.Optional }
);如下所示访问您的URI:
http://localhost:42201/api/Extract/GetMessage/Q3或
http://localhost:42201/api/Extract/GetMessage/?quotename=Q3https://stackoverflow.com/questions/21102561
复制相似问题