webapi 控制器调用错误的方法

webapi controller calling wrong method

我已经使用 c# 和 webApi 2.0 实现了一个通用控制器

http://localhost:4200/api/projects 将正确调用 GetAllItems() 和 return 预期结果

http://localhost:4200/api/projects/1 不调用 GetItemById( ) 相反,它调用 GetAllItems( )

在构建泛型之前,我为项目构建了一个具体的控制器。 它是一个 cut/paste 并且它调用了正确的方法。 我的想法是我的路线在泛型上是错误的,或者应该有所不同,因为它是泛型,但我似乎无法提出正确的语法。

当 url 包含尾随整数时,为什么泛型没有调用正确的方法?

我尝试过的事情w.o成功

重新排序方法

将动词增强为 System.Web.Http.HttpGet

将 GET 和 ROUTE 合并为 1 个标记,逗号分隔

在函数签名中的 itemId 参数上指定 [FromUri]

注释掉 GetAllItems() --> 请求的资源不支持 http 方法 'GET'(这一定是个大线索,但对我来说...)

这是通用模板的简短列表

    [RoutePrefix("api/{contoller}")]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class baseController<T, T_Q > : ApiController 
                where T:pgBaseClass, new()
                where T_Q : sbQuery<T> , new()
                 
    {

        

        [HttpGet]
        [Route("")]
        public CustomJsonStringResult GetAllItems()
        {
            T_Q q = new T_Q();
            List<T> l = q.Items();


            string json = q.ListToJSON(l);

            return JSONStringResultExtension.JSONString(this, json, HttpStatusCode.OK);
        }


        [HttpGet]
        [Route("{itemId:int}")]
        public IHttpActionResult GetItemById(int itemId)
        {
            T_Q q = new T_Q();
            T p = q.GetById(itemId);

            if (p == null)
            {
                return JSONStringResultExtension.JSONString(this, "Item not Found", HttpStatusCode.NotFound);
            }
            else
            {
                return JSONStringResultExtension.JSONString(this, p.JSON, HttpStatusCode.OK);
            }
        }
}

这是使用通用

的项目控制器的定义
  public class ProjectsController : baseController<pgProject,pgProjectQuery>
    {
  }

这是按预期工作的非通用控制器的简短列表。 (我排除了一个或另一个以使项目编译和 运行...)

 [RoutePrefix("api/projects")]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class  ProjectController : ApiController
    {

        //[HttpGet]
        [Route("")]
        public CustomJsonStringResult GetAllItems()
        {
            pgProjectQuery ag = new pgProjectQuery();
            ag.SortExpression = " [Name] asc ";
            List<pgProject> l = ag.Items();


            string json = ag.ListToJSON(l);

            return JSONStringResultExtension.JSONString(this, json, HttpStatusCode.OK);
        }

        

        [HttpGet]
        [Route("{itemId:int}")]
        public IHttpActionResult GetItemById(int itemId)
        {
            pgProjectQuery q = new pgProjectQuery();
            pgProject p = q.GetById(itemId);
            
            if (p == null)
            {
                return JSONStringResultExtension.JSONString(this, "Item not Found", HttpStatusCode.NotFound);
            }
            else
            {
                return JSONStringResultExtension.JSONString(this, p.JSON, HttpStatusCode.OK);
            }
        }
}

我在 webApiConfig.js

中配置了这个

这里我定义了唯一的路由,带有一个名为 id 的可选参数。 我在我的 GetItemById() 方法中更改了参数名称,这有效。

public static void Register(HttpConfiguration 配置) { // Web API 配置和服务

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.EnableCors();
    
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

}


  [System.Web.Http.HttpGet]
        [Route("{id:int}")]
        public CustomJsonStringResult GetItemById([FromUri] int id){...}

我无法解释的是为什么非通用控制器按预期工作但基于通用的控制器却没有。 我相信现在情况可能 'more correct',只是希望我有一个事实的答案。 我的补丁方法也 运行 遇到了同样的问题。将参数重命名为 id 并且有效。

希望这对在线的人有所帮助。