Generic webAPI method based on parameter types of arrays

513 views Asked by At

I have a webAPI in Asp.net 4.5.

I have some code like this

    public string[] Get([FromUri] string[] filterStrings)
    {
        return filterStrings;
    }
    public int[] Get([FromUri] int[] nums)
    {
        return nums;
    }

right now i get this ExceptionMessage

"ExceptionMessage": "Multiple actions were found that match the request"

Is it possible to accept an array of strings and then an array ints and have different methods be called in the same controller or do I need do these two different operations in different controllers?

My assumption is I would have to do the later because if I am sending data from the URI I could send all Ints but it would not if those ints were meant to goto the string method or the int method. I just wanted to ask if there was a preferred way rather than putting them in separate controllers but this scenario seems to be the deal breaker.

heres the urls I am using

url 1 for the top method

http://localhost:7656/api/SearchAll?filterStrings=Tebow&filterStrings=Tim&filterStrings=11

url 2 for the bottom method of ints

http://localhost:7656/api/SearchAll?nums=11&nums=96&nums=55
2

There are 2 answers

1
JotaBe On BEST ANSWER

This looks like a corner case in which Web API is unable to select the action based upon the parameter names. Perhaps because an array is somewhat optional (it can be empty, so technically posting other parameters yields an empty array, not a missing parameter). The two easier solutions I can find for this problem are:

  1. using attribute routing, so that each action has a different URL
  2. implement a simple action that receives both parameter arrays, and include in it the logic to determine which code to run depending on the arrays being empty or having elements

EDIT: Added samples

This sample code works with both URLs in the question:

public string[] Get([FromUri] int[] nums, [FromUri] string[] filterStrings)
{
    if (nums.Length > 0)
    {
        return nums.Select(n => n.ToString()).ToArray();
    }
    if (filterStrings.Length > 0)
    {
        return filterStrings;
    }
    throw new HttpException("Missing parameters!");
}

I don't include a sample for attribute routing, because you have to take into account several things that are perfectly explained in the link above, like registering attribute routes, and so on. In this case you need to add attributes to the actions, and you need to use different URLs for invoking them, for example: /api/SearchAll/ByNumber/?nums=11&nums=96&nums=55

2
ragerory On

I think your understanding of overloading might be slightly off. However, you can accomplish the above by using Generics.

public static T[] Get<T>([FromUri] T[] t)
{
    T[] result = new T[count]; // count being size of your array
    // do something
    return result;
}