I am working on creating a Web API using ASP.NET Web API. I’m currently stubbing out functionality on my endpoints so that I can then start developing against it.
My WebApiConfig.cs file looks like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionAPI",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { action = RouteParameter.Optional }
);
In my UsersController.cs file I have these methods:
//Maps to /Users endpoint
[HttpGet]
public IEnumerable<User> GetAllUsers()
{
//Code
}
//Maps to /Users/{id} endpoint
[HttpGet]
public User GetUser(int id)
{
//Code
}
//Maps to /Users/{id}/Enrollments endpoint
[HttpGet, ActionName("Enrollments")]
public IEnumerable<Enrollment> GetUserEnrollments(int id)
{
//Code
}
//Maps to /Users/{id}/Enrollments/{id}
[HttpGet, ActionName("Enrollments")]
public IEnumerable<Enrollment> GetUserEnrollment(int userid, int id)
{
//Code
}
How do I prevent /Users/GetUser from being a valid route?
Using [NonAction] on GetUser(int id) prevents it from working completely.
EDIT: Here is the current output from /Users/GetUser
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Multiple actions were found that match the request: Byui.ILearnAPI2.Business.Entities.User GetUser(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController System.Collections.Generic.IEnumerable`1[System.String] GetUserEnrollments(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext) at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext) at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
</StackTrace>
</Error>
After reviewing your post again, I think that you are not looking at the error correctly.
Because of the way you have your controller configured, there is an ambiguous route.
Multiple actions were found that match the request:
GetUser(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController
GetUserEnrollments(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController
GetUser and GetUserEnrollments share the same route. From what I can tell GetUser is not going to work if you pass it an int or a string or whatever, because it does not know how to resolve properly.
You can add a route config before your default to resolve the issue.