Reputation: 220
I've hit an issue with webapi attribute routing. I am calling the following route: assessment/assessments/assessmenttypes
as an HttpPost
. I'm getting the error that multiple controller types match the url. The problem is that they definitely don't match. Initially when I first got this issue I was using different route prefixes, however I read that webapi can ignore route prefixes, so I changed all the routes to make them unique, so the only HttpPost
s which are in the "matching controllers" are defined as follows:
[Route("assessments"), HttpPost]
public async Task<System.Int32> PostCreate([FromBody]Assessment assessment)
and
[Route("assessments/assessmenttypes"), HttpPost]
public async Task<System.Int32> PostCreate([FromBody]AssessmentType assessmentType)
Both controllers have the same RoutePrefix of: [RoutePrefix("assessment")]
Can anyone help please, this is very frustrating.
Thanks in advance!
Upvotes: 2
Views: 671
Reputation: 2256
What you need to understand first at all is how routing works, that's the key to solve your problem. I can update my answer later if you give me more information (at this moment it looks like you didn't post all the required information)
As you know, routing is the process of matching requests to routes. The handler that does the magic is the HttpRoutingDispatcher with some help of extra libraries, but basically the dispatcher resolves the request. The final goal of processing the route is to identify two elements:
You have two different ways of resolving routes, convention-based (templates) or by attributes. It's a good idea to be consistent to avoid confusions specially when the application grows. The routing has two different parts, fixed segments (they must match exactly) and variables (denoted as you know by {})
The request verbs are matched in two different ways, with the attribute [HttpGet] [HttpPost] [HttpPut] Or confusingly in my opinion using the first part of the method, if you have 3 different methods not marked with attributes the WebApi assumes the first letters try to indicate the verb:
From the official documentation if you try the following template:
routeTemplate: "api/{controller}/{id}"
And you make a request from Ajax like the following:
$.ajax("/api/today/dayofweek", {
The following controller will fail (nearly always)
public class TodayController : ApiController {
[HttpGet]
public string DayOfWeek() {
return DateTime.Now.ToString("dddd");
}
[HttpGet]
public int DayNumber() {
return DateTime.Now.Day;
}
Because it's nearly impossible to establish which one is the correct one (a human being can of course, but unfortunately machines need more programming to work with fuzzy logic) :)
The problem in your case it's not both start with the same fixed route, the problem is that it's not possible to identify whether you're saying the second part belongs to a variable or it's a fixed part (it's ambiguous) Giving you an example; how could we establish the meaning of this?
From an architectural point of view the reality is (based on Api design) that I don't think /assestmenttypes is a subordinated resource of /assestments. If you want to design a RESTful ROA Api assestmenttypes are correctly indicated as a resource if the type depends on the assestment (as a child, not as an attribute). I would suggest you to review your paths too.
Upvotes: 0