Multiple Get Methods with the Action Method Selector Attribute in .NET Core
Full source code available here.
In .Net Core Web Api it is not possible for the routing mechanism to distinguish between the following action methods.
public string GetSomething(int id, int something)
and
public string GetAnother(int id, int another)
But with the help of an ActionMethodSelectorAttribute
we can tell the methods apart.
Step 1
Add a new class called QueryStringConstraint
and inherit from ActionMethodSelectorAttribute
.
1public class QueryStringConstraint : ActionMethodSelectorAttribute
2{
3 public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
4 {
5 IList<ParameterDescriptor> methodParameters = action.Parameters;
6
7 ICollection<string> queryStringKeys = routeContext.HttpContext.Request.Query.Keys.Select(q => q.ToLower()).ToList();
8 IList<string> methodParamNames = methodParameters.Select(mp => mp.Name.ToLower()).ToList();
9
10 foreach (var methodParameter in methodParameters)
11 {
12 if (methodParameter.ParameterType.Name.Contains("Nullable"))
13 {
14 //check if the query string has a parameter that is not in the method params
15 foreach(var q in queryStringKeys)
16 {
17 if (methodParamNames.All(mp => mp != q))
18 {
19 return false;
20 }
21 }
22
23 if(queryStringKeys.All(q => q != methodParameter.Name.ToLower()))
24 {
25 continue;
26 }
27 }
28 else if (queryStringKeys.All(q => q != methodParameter.Name.ToLower()))
29 {
30 return false;
31 }
32 }
33 return true;
34 }
35}
Step 2
Add the QueryStringConstraint
to the action methods that need to be distinguished by query string parameters.
1[QueryStringConstraint]
2public string GetAnother(int id, int another)
3{
4 return $"GetAnother {id} {another}";
5}
6
7// http://localhost:62922/api/values/?id=1&something=22
8[QueryStringConstraint]
9public string GetSomething(int id, int something)
10{
11 return $"GetSomething {id} {something}";
12}
Full source code available here.