C# 在web api控制器中进行通用查询/getbyspecification?

C# 在web api控制器中进行通用查询/getbyspecification?,c#,asp.net-mvc,asp.net-mvc-4,asp.net-web-api-routing,C#,Asp.net Mvc,Asp.net Mvc 4,Asp.net Web Api Routing,我有一个带有一些CRUD操作的典型API。我通常需要根据不同的参数获取某些对象 一种方法是采用如下方法: GetProjectsByCustomerId(int customerId); GetProjectsBySigneeId(int signeeId); 但是,在我的服务层(ProjectService在本例中),我通常使用如下方法,ProjectSpecification通常有很多字段甚至列表: public IEnumerable<Project> GetBySpecif

我有一个带有一些CRUD操作的典型API。我通常需要根据不同的参数获取某些对象

一种方法是采用如下方法:

GetProjectsByCustomerId(int customerId);
GetProjectsBySigneeId(int signeeId);
但是,在我的服务层(
ProjectService
在本例中),我通常使用如下方法,
ProjectSpecification
通常有很多字段甚至列表:

public IEnumerable<Project> GetBySpecification(ProjectSpecification projectSpecification)
但假设我打开此URL:

/api/Projects?CustomerId=2
这不会解析为
ProjectSpecification
viewmodel。但是,如果我将控制器签名更改为:

public IEnumerable<Project> GetProjects(int customerid) { }
public IEnumerable GetProjects(int-customerid){}
它会起作用,因为它是一种简单的类型


我当然可以构建一些参数地狱,但我想我缺少了一些非常明显的MVC魔力——可能是在路由中?:-)

参考文档

要强制Web API从URI读取复杂类型,请添加
[FromUri]
参数的属性

例如假设

public class ProjectSpecification {
    public int CustomerId { get; set; }
    //...other properties
}

public class ProjectsController : ApiController {
    [HttpGet]
    public IHttpActinoResult GetProjects([FromUri]ProjectSpecification projectSpecification) {
        return Ok(projectSpecification);
    }
}
客户机可以将
CustomerId
值放入查询字符串中

例如:

/api/Projects?CustomerId=2

Web API将使用它们构建一个
ProjectSpecification
,并将
CustomerId
设置为
2

作为示例的一部分显示
ProjectSpecification
。还可以查看参数上的
FromUri
属性
ProjectSpecification
类可以正常工作,但您可能需要构建自定义模型绑定器(一点也不难)。或者你可能想看看OData,它几乎为你做了这一切。@DavidG我想你是对的,OData可能是我想要的,但为了这个目的,让我们继续休息。这里最简单的定制模式活页夹示例是什么?(谢谢btw=))看看这里:对于web api,请看这个<代码>[FromUri]对于这个场景应该足够简单。
public class ProjectSpecification {
    public int CustomerId { get; set; }
    //...other properties
}

public class ProjectsController : ApiController {
    [HttpGet]
    public IHttpActinoResult GetProjects([FromUri]ProjectSpecification projectSpecification) {
        return Ok(projectSpecification);
    }
}