0

After a lengthy discussion in terms of how our API would need to behave due to limitations of the backend design, I'd like to have the following possibilities:

1. /students/251/employment <--- allow GET, PUT, POST
2. /students/251/employment/jobs <--- allow GET only
3. /students/251/employment/jobs/435 <--- allow all verbs
4. /students/251/employment/internships <--- allow GET only
5. /students/251/employment/internships/664 <--- allow all verbs

These cases are working for GET requests. I'm struggling when I try to do a PUT request for case #1 and #3:

Case #1 Error
  No HTTP resource was found that matches the request URI '/students/251/employment/221'.,
  No action was found on the controller 'Employment' that matches the name '221'.

Case #3 Error
  The requested resource does not support http method 'PUT'.

Here's an abridged version of my controller methods:

public ApiEmploymentGetResult Get(long id) {            
  // code omitted
}        

[HttpGet]
public IEnumerable<ApiJob> Jobs(long id) {
  // code omitted
}

[HttpGet]
public IEnumerable<ApiOwnVenture> OwnVenture(long id) {
  // code omitted
}

public void Put(long id, MyModel model) {
  // breaks before getting here
}

My routing looks like this, but I'm not sure it's quite right, even though the GETs are working.

context.Routes.MapHttpRoute(
  name: "V1/EmploymentApi",
  routeTemplate: "api/v1/Employment/{action}/{jobId}",
  defaults: new { controller = "Employment", jobId = RouteParameter.Optional, action = "Get" }
);

Case #1 seems to be conflicting due to the framework expecting an action rather than the 221. I'd like to be able to get all of these cases working.

Adam Levitt
  • 10,316
  • 26
  • 84
  • 145
  • If your routing is 'api/v1/Employment/{action}/{jobId}' how on earth is it matching anything like '/students/251/employment/jobs'? – Jon Susiak Nov 19 '13 at 08:52

1 Answers1

2

You may want to look at Attribute Routing (Web API 1 and Web API 2).

public class StudentsController : ApiController
{
    [HttpPut]
    [Route("students/{studentId}/employment")]
    public void UpdateStudentEmployment(int studentId) { ... }

    [HttpPut]
    [Route("students/{studentId}/employment/jobs/{jobId}")]
    public void UpdateStudentEmploymentJob(int studentId, int jobId) { ... }
}
Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70