How to pass multiple parameters to a get method in ASP.NET Core
Solution 1
You also can use this:
// GET api/user/firstname/lastname/address
[HttpGet("{firstName}/{lastName}/{address}")]
public string GetQuery(string id, string firstName, string lastName, string address)
{
return $"{firstName}:{lastName}:{address}";
}
Note: Please refer to the answers from metalheart
and Mark Hughes
for a possibly better approach.
Solution 2
Why not using just one controller action?
public string Get(int? id, string firstName, string lastName, string address)
{
if (id.HasValue)
GetById(id);
else if (string.IsNullOrEmpty(address))
GetByName(firstName, lastName);
else
GetByNameAddress(firstName, lastName, address);
}
Another option is to use attribute routing, but then you'd need to have a different URL format:
//api/person/byId?id=1
[HttpGet("byId")]
public string Get(int id)
{
}
//api/person/byName?firstName=a&lastName=b
[HttpGet("byName")]
public string Get(string firstName, string lastName, string address)
{
}
Solution 3
To parse the search parameters from the URL, you need to annotate the controller method parameters with [FromQuery]
, for example:
[Route("api/person")]
public class PersonController : Controller
{
[HttpGet]
public string GetById([FromQuery]int id)
{
}
[HttpGet]
public string GetByName([FromQuery]string firstName, [FromQuery]string lastName)
{
}
[HttpGet]
public string GetByNameAndAddress([FromQuery]string firstName, [FromQuery]string lastName, [FromQuery]string address)
{
}
}
Solution 4
I would suggest to use a separate dto object as an argument:
[Route("api/[controller]")]
public class PersonController : Controller
{
public string Get([FromQuery] GetPersonQueryObject request)
{
// Your code goes here
}
}
public class GetPersonQueryObject
{
public int? Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Address { get; set; }
}
Dotnet will map the fields to your object.
This will make it a lot easier to pass through your parameters and will result in much clearer code.
Solution 5
I think the easiest way is to simply use AttributeRouting
.
[Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
public string Get(int paramOne, int paramTwo)
{
return "The [Route] with multiple params worked";
}
Related videos on Youtube
mstrand
Updated on November 12, 2021Comments
-
mstrand over 2 years
How can I pass in multiple parameters to Get methods in an MVC 6 controller. For example I want to be able to have something like the following.
[Route("api/[controller]")] public class PersonController : Controller { public string Get(int id) { } public string Get(string firstName, string lastName) { } public string Get(string firstName, string lastName, string address) { } }
So I can query like.
api/person?id=1 api/person?firstName=john&lastName=doe api/person?firstName=john&lastName=doe&address=streetA
-
metalheart about 8 yearswhy would you need this? parameter binding from the query string happens by default...
-
mstrand about 8 yearsI have tried both but overloading as I try to do fails with or without [FromQuery]
-
mstrand about 8 yearsYes, I solve it now using just one action taking in all attributes that I want to be able to search out a Person on. Like a general search. I would prefer though if there where a way to have overloaded actions in a controller but that might not be the case.
-
Mark Hughes about 8 years@mstrand I've updated - give that a go, see the extra
[HttpGet]
annotations, the different method names, and the specific route in[Route]
- the routes should be fully explicit now which eliminates a few possible problems. -
Seb Andraos over 6 yearsAs stipulated in the documentation for parameter binding[1] simple types, "(int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string" will automatically be read fro the URI. The attribute [FromURI] is required when the parameter in not one of these types to force the reading of those from the URI rather than their default location, the body. For the sake of completeness the [FromBody] attribute does essentially the opposite with complex types. [1] docs.microsoft.com/en-us/aspnet/web-api/overview/…)
-
Phillip Copley over 6 yearsUntil you need to get everyone with the same last name :)
-
ZZZ about 6 yearsthis does not work with .net core 2.0, since no valid url template is actually generated.
-
k4s about 5 yearsCan I use preferred reference type? That is,
int paramOne, string paramTwo
-
Thomas Levesque almost 5 yearsThat's a really bad way to design API routes... Not RESTful at all.
-
Anytoe almost 5 yearsUse [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo?}")] if you want your second parameter to be optional
-
Bernoulli IT almost 5 yearsThe above approach looks very cumbersome, don't get why it has so many upvotes.
-
Bruno Santos over 4 years@ThomasLevesque What did you mean by it no being RESTful?
-
Thomas Levesque over 4 years@BrunoSantos it doesn't follow the principles of REST. URIs are supposed to uniquely identify resources. This is not the case here (there might be multiple persons with the same first and last name, and an address can certainly not be considered an identifier)
-
Bruno Santos over 4 years@ThomasLevesque Oh I see what you mean, my question though is: having 3 params to uniquelly identify a resource, instead of just 1 param, is it a bad practice?
-
Thomas Levesque over 4 years@BrunoSantos no, not that in itself. My issue is only about the route design in this specific case.
-
Arie over 3 yearsand how to pass values in link?
-
Sebastian over 3 yearsWhat do mean with that? You can provide the values as query parameters like
/api/controller?firstname={firstname}&lastname={lastname}
-
Sabir Hossain over 3 years@metalheart without
[FromQuery]
sometimes the first param value comes as theRouteName
-
Ashok Patel over 3 yearsIf you have single parameter to pass this is good approach, otherwise should use query string
-
Naveen Kumar V over 3 yearsGood and Simple one :)
-
Oleg Ivanov almost 3 yearsI can't believe such answers receive so many upvotes. Do you really build your api in such way?
-
Chris Fremgen over 2 years@OlegIvanov Care to share your answer? Or contribute anything useful?
-
RedRose about 2 yearsThis is good when you have a growing and long list of filters and sort criteria and you want to keep the your endpoint simple and offload the validation and parsing of query to another class or service.
-
ZecosMAX about 2 yearsYour solution should have a checked sing. It's simple and does exactly what was requested.
-
Onurkan Bakırcı about 2 yearsThis is not suitable for API conventions. By the question firstname, lastname and address should be passed as query params not route params.