抽象通用ODataController类导致'找不到HTTP资源'

Mic*_*uso 17 asp.net odata asp.net-web-api

我试图在VS 2013中抽象自动生成的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)));
     }  
 }
Run Code Online (Sandbox Code Playgroud)

IIdentifiable 是一个强制T参数具有可读/可写Id整数属性的接口.

实现看起来像这样(POCO和DataContexts应该已经创建)

public class MyObjectsController : ODataControllerBase<MyObject,MyDbContext>
{
    public MyObjectsController() : base()
    {
    }

    // That's it - done because all the repetitive code has been abstracted.
}
Run Code Online (Sandbox Code Playgroud)

现在,我的WebApiConfig的Register函数仅包含以下内容:

public static void Register(HttpConfiguration config)
{
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<MyObject>("MyObjects");
    config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());  
}
Run Code Online (Sandbox Code Playgroud)

我运行项目,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>
Run Code Online (Sandbox Code Playgroud)

缺什么?我应该删除什么?这是我们不能做的事情,即我们真的需要ODataController直接继承没有中间父类吗?

小智 -1

为了确定要调用哪个操作,框架使用路由表。Web API 的 Visual Studio 项目模板创建默认路由:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

按操作名称路由

使用默认路由模板,Web API 使用 HTTP 方法来选择操作。但是,您也可以创建一个将操作名称包含在 URI 中的路由:

routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

我配置的配置如下:

config.Routes.MapHttpRoute(
            name: "GetMessage",
            routeTemplate: "api/{controller}/{action}/{quoteName}",
            defaults: new { quoteName = RouterParameters.Optional }
        );
Run Code Online (Sandbox Code Playgroud)

像这样访问你的 URI:

http://localhost:42201/api/Extract/GetMessage/Q3
Run Code Online (Sandbox Code Playgroud)

或者

http://localhost:42201/api/Extract/GetMessage/?quotename=Q3
Run Code Online (Sandbox Code Playgroud)