Reputation: 97
With the routeTemplate defined as "api/{controller}/{id}" and having below methods in my controller (ValuesController)
[HttpGet]
public IEnumerable<string> GetX()
{
return new string[] { "xx1", "xx2" };
}
[HttpGet]
public IEnumerable<string> GetY([FromUri]Customer c)
{
return new string[] { "c1", "c2" };
}
public class Customer
{
public bool IsMarried { get; set; }
public string CustName { get; set; }
}
Using the url - "/api/values?IsMarried=false&CustName=aa" results in error - "Multiple actions were found that match the request..." . I am not able to fix above issue without changing the routeTemplate to something like "api/{controller}/{action}/{id}". If anyone knows how to fix above without changing the routeTemplate kindly suggest.
Upvotes: 0
Views: 3621
Reputation: 472
Use simple types and map them in the controller:
[HttpGet]
public IEnumerable<string> GetY(bool IsMarried, string CustName)
{
var cust = new Customer {IsMarried = IsMarried, CustName = CustName};
return new string[] { "c1", "c2" };
}
Note that you will lose functionalities like ModelState.IsValid
so you would need to invoke the validators manually.
Take a look at Action Selection section to see how it works for simple vs complex params.
Upvotes: 1
Reputation: 62213
If you cant specify action names then you have two options.
Create an overload that takes a default (null for reference type) parameter. Depending on the state o the parameter do the approriate action. As your sample is very abstract I have no idea if this would work for you or not.
[HttpGet]
public IEnumerable<string> GetY([FromUri]Customer c = default(Customer))
{
if(c == null /* or some other state */)
return new string[] { "xx1", "xx2" };
return new string[] { "c1", "c2" };
}
Create a new Controller and define your additional action there. If the actions are very different in nature this might be a better solution. No code sample here is needed, just create a new controller and move the existing method.
Upvotes: 1
Reputation: 3631
Solution one: Routing
[RoutePrefix("api")]
public class FooController : ApiController
{
[Route("Foo/getall")]
[HttpGet]
public IEnumerable<string> GetX()
{
return new string[] { "xx1", "xx2" };
}
[Route("foo/search")]
[HttpGet]
public IEnumerable<string> GetY([FromUri]Customer c)
{
return new string[] { "c1", "c2" };
}
public class Customer
{
public bool IsMarried { get; set; }
public string CustName { get; set; }
}
}
Remember to add attribute route mapping:
configuration.MapHttpAttributeRoutes();
Solution two: Optional parameters
[RoutePrefix("api")]
public class FooController : ApiController
{
[HttpGet]
public IEnumerable<string> GetY([FromUri]Customer c)
{
if(c == null)
// no parameters where set.
if(c.IsMarried != null)
// do stuff
// etc....
return new string[] { "c1", "c2" };
}
public class Customer
{
public bool? IsMarried { get; set; }
public string CustName { get; set; }
}
}
Upvotes: 1