2

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:

  • /api/projects (empty specification, return full list)
  • /api/projects?customerid=2 (gets projects for customer with id 2)
  • /api/projects?signeeid=2,3 (get projects with signee id 2 and 3)

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? :-)

6
  • Show ProjectSpecification as part of the example. Also look into the FromUri attribute on the parameter Commented Aug 15, 2017 at 14:26
  • 1
    The ProjectSpecification class would work fine, but you may need to build a custom model binder (not hard at all). Alternatively you may want to look at OData which pretty much does this for you anyway. Commented Aug 15, 2017 at 14:27
  • @DavidG I think you're right that ODATA would probably be what I want, but for the purpose here lets stick with REST. What would be the simplest example of a custom modal binder here? (Thanks btw =) ) Commented Aug 15, 2017 at 14:29
  • Take a look here: learn.microsoft.com/en-us/aspnet/core/mvc/advanced/… Commented Aug 15, 2017 at 14:30
  • For web api look at this learn.microsoft.com/en-us/aspnet/web-api/overview/… . [FromUri] should be simple enough for this scenario. Commented Aug 15, 2017 at 14:31

1 Answer 1

1

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 .

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.