1

I've this GET method in my MVC Web Api:

public IQueryable<Employee> GetEmployeeByJobTitle(List<string> jobTitles)
{
    var employeeByJobTitle = from e in db.Employee
                             where jobTitles.Contains(e.JobTitle)
                             select e;
    return db.Employee;
}

because I need to get a set of employees by job titles. So if I want all employees with job Title in "Production Technician - WC60" and "Production Supervisor - WC60", I need to call this URI

http://localhost:60054/api/Employee/GetEmployeeByJobTitles/?jobTitles[0]=%22Production%20Technician%20-%20WC60%22&jobTitles[1]=%22Production%20Supervisor%20-%20WC60%22

As you can see the query string is huge and complex. Now, I need to call this method from a client console using HttpClient class from Web.API.Client.Libraries. Is there an easy way to create a method builting the above query string starting from the object:

var jobTitles = new List<string>
{
    "Production Technician - WC60",
    "Production Supervisor - WC60"
};

Something like

string BuiltUriFromObject(List<string> jobTitles){};
abatishchev
  • 98,240
  • 88
  • 296
  • 433
LarAnto
  • 136
  • 1
  • 13
  • 2
    Do you have to use a GET? With complex data, a POST would be better. – Tim Feb 03 '18 at 18:50
  • With regards to your question, you'd probably be better served passing a JSON object in as the parameter, then parsing it in the handler. I'd suggest creating a container for that JSON object and using that as the parameter. – Kevin Fichter Feb 03 '18 at 18:52
  • With regards to the code you posted, your method returns the entire Employee table; is that really what you want? Also, you might get "Context has been disposed" exceptions with this approach; it would probably be better to materialize the resultset and return an IEnumerable, that way you can sanitize the output and mitigate the risk of sending PII over the wire. Just give the requestor what they need, not more. – Kevin Fichter Feb 03 '18 at 18:55
  • Thank you Tim. I'm pretty new to Web Api. I've thought to use a POST request but is it correct to use a POST request in order to get a list of object? I still had to call my Web Api method `GetEmployeeByJobTitles` but it would perform a POST action. I'm pretty confuse. Can you help me? – LarAnto Feb 03 '18 at 18:57
  • So @K_foxer9 I would first convert `List jobTitles = ... ` in a json object and then using this string to compose the uri with something like that https://stackoverflow.com/questions/12610585/convert-json-data-to-querystring-in-c-sharp-get-request – LarAnto Feb 03 '18 at 19:06
  • The JSON approach would use a DTO similar to the following: `public class MyDto {public List Query;}`. The api endpoint would start with `public IEnumerable Get(string stuff) { var names = JsonConvert.DeserializeObject(stuff);` The query string would be `localhost:50237/api/values?stuff={'Query':['item1','item2']}` – Kevin Fichter Feb 03 '18 at 19:49

1 Answers1

2

This situation suits the FromUri attribute which will create the specified model from the querystring.

Declare the controller like this

[HttpGet]
public IHttpActionResult GetEmployeeByJobTitle([FromUri]string[] jobTitles)
{
    var employeeByJobTitle = from e in db.Employee
                             where jobTitles.Contains(e.JobTitle)
                             select e;
    return Ok(employeeByJobTitle.ToArray());
}

Call this method by adding as many titles you like but declare all titles to the same parameter name jobTitles="CIO"&jobTitles="CTO" then the FromUri will create a list with List<string>{"CIO", "CTO"}.

In your case, something like this

api/Employee?jobTitles=%22Production%20Technician%20-%20WC60%22&jobTitles=%22Production%20Supervisor%20-%20WC60%22
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69