Lars Holdgaard
Lars Holdgaard

Reputation: 9976

Making a generic query / getbyspecification in web api controller?

I have a typical API with some CRUD operations. I typically need to get certain objects, based on different parameters.

One way to do it would be to have methods like:

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

However, in my service layer (ProjectService in this case) I usually use a method such as the following where ProjectSpecification typically has quite a lot of fields and even lists:

public IEnumerable<Project> GetBySpecification(ProjectSpecification projectSpecification)

That means, in my dream world I would like to have endpoints such as:

My question is - how is this done

My first attempt was adding this in my ProjectController (calling my ProjectService):

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

But lets say I open this URL:

/api/Projects?CustomerId=2

This is not parsed into a ProjectSpecification viewmodel. However, if I change my controller signature to:

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

It would work, because it's a simple type.

I could of course build some parameter-hell, but I guess there is something super obvious MVC magic I am missing - probably in the routing? :-)

Upvotes: 2

Views: 283

Answers (1)

Nkosi
Nkosi

Reputation: 247413

Referencing documentation

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

To force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter.

For example assuming

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

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

The client can put the CustomerId value in the query string.

For example:

/api/Projects?CustomerId=2

and Web API will use them to construct a ProjectSpecification with the CustomerId set to 2 .

Upvotes: 1

Related Questions