In my API, I’d like to have routes like GET /api/v1/widgets/1,2,3 and GET /api/v1/widgets/best-widget,major-widget,bob-the-widget
public class WidgetsController : MyApiController
{
public ActionResult Show(IEnumerable<int> ids)
{
}
public ActionResult Show(IEnumerable<string> names)
{
}
}
I’ve got routes set up to get me to the action, but I can’t figure out how to turn 1,2,3 into new List<int>(){1, 2, 3} and so on. Of course, I could just take a string and parse it in my action, but I’d like to avoid going that route.
One thing that came to mind was to put something in the OnActionExecuting method, but then I wasn’t sure exactly what to put in there (I could hack something together, obviously, but I’m trying to write something reusable.)
The main questions I have are how to know whether I need to do anything at all (sometimes the ValueProviders upstream will have figured everything out), and how to handle figuring out the type to cast to (e.g., how do I know that in this case I need to go to a collection of ints, or a collection of strings, and then how do I do that?)
By the way, I had the idea of implementing a ValueProvider as well, but got lost on similar questions.
To avoid polluting each controller action that needs to receive this parameter I would recommend a custom model binder:
and then register the model binder in
Application_Start:and finally your controller action might look like this (and from what I can see in your question it already does look like this :-)):
and the custom model binder will take care for parsing the
idsroute token to the correspondingIEnumerable<int>value.You could do the same with the
IEnumerable<string>where you would simply remove the.Selectclause in the corresponding model binder.