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

时间:2017-08-15 14:14:31

标签: c# asp.net-mvc asp.net-mvc-4 asp.net-web-api-routing

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

一种方法是使用以下方法:

GetProjectsByCustomerId(int customerId);
GetProjectsBySigneeId(int signeeId);

但是,在我的服务层(本例中为ProjectService)中,我通常使用如下方法:ProjectSpecification通常包含很多字段甚至列表:

public IEnumerable<Project> GetBySpecification(ProjectSpecification projectSpecification)

这意味着,在我的梦想世界中,我希望有一些端点,例如:

  • /api/projects(空说明,返回完整列表)
  • /api/projects?customerid=2(为ID为2的客户获取项目)
  • /api/projects?signeeid=2,3(获取signee id为2和3的项目)

我的问题是 - 这是怎么做的

我的第一次尝试是在ProjectController(调用我的ProjectService)中添加此内容:

public class ProjectsController : ApiController
{
    public IEnumerable<Project> GetProjects(ProjectSpecification projectSpecification)
    {
        var projects = _projectService.GetBySpecification(projectSpecification);
        return projects;
    }
}

但我可以说我打开这个网址:

/api/Projects?CustomerId=2

这不会被解析为ProjectSpecification视图模型。但是,如果我将控制器签名更改为:

public IEnumerable<Project> GetProjects(int customerid) { }

它会起作用,因为它是一种简单的类型。

我当然可以构建一些参数 - 地狱,但我想有一些超级明显的MVC魔法我错过了 - 可能在路由? : - )

1 个答案:

答案 0 :(得分:1)

参考文档

Parameter Binding in ASP.NET Web API : [FromUri]

  

要强制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将使用它们构建ProjectSpecificationCustomerId设置为2