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.

comments powered by Disqus

Related