0

I am new to ASP.Net WebAPI and I'm trying to use the NorthWind database to practice. Now, I have a ProductsController which contains a GetAllProducts and a GetAllProductsById actions.

On the client-side, I have a multiselect dropdown control which is been populated with the categories of products from the CategoriesController class.

I want to populate a second dropdown control (not a multiselect) with the Products from the Categories that was selected in the category dropdown list.

My GetAllProductsById controller looks like this:

 public IHttpActionResult GetAllProductsById([FromUri]int[] id)
 {
    using (var ctx = new NorthwindEntities())
    {
        <some codes...>
    }
    return Ok(productList);
 }

Calling this service from the client, the URL look like this: http://localhost:1234/api/Products/GetAllProductsById?id=1&id=2&id=3

This is looks good with few parameters but what if the User selects more categories (let's say 30 out of 40 categories)? This means the URL would be so long.

So, I decide to use a POST to do a GET's job by decorating my action with HttpPost:

 [HttpPost]
 public IHttpActionResult GetAllProductsById([FromBody]int[] id)

This allows me to send the id parameters from the Body of my request.

Now, I am wondering if this style is correct or if someone can point me to a much cleaner way of passing a long list of parameters from a client to my webservice.

Thanks in advance.

NB:

  • Using Elasticsearch is not an option at the as suggested in the link below: HTTP GET with request body
  • I tried using a modal class but it also has the same effect http://localhost:1234/api/Products/GetAllProductsById?input.id=1&input.id=2
adjaharrison
  • 35
  • 1
  • 9
  • Possible duplicate of [HTTP GET with request body](https://stackoverflow.com/questions/978061/http-get-with-request-body) – Stefano d'Antonio Jun 17 '17 at 07:43
  • I have read the suggested link but it does not seem to address the URL part. My concerned is the long list of parameters that would be displayed with the URL, that is why I decided to use `POST`. But I was wondering if there is a better way aside using Elasticsearch. – adjaharrison Jun 17 '17 at 08:14

2 Answers2

1

You could do something a bit hacky: use HTTP headers.

First the client should add the ID list as a header to its HTTP request (C# example follows):

var webRequest = System.Net.WebRequest.Create(your_api_url);
webRequest.Headers.Add("X-Hidden-List", serialized_list_of_ids);

And then on the API side:

[HttpGet] 
public IHttpActionResult GetAllProductsById() 
{ 
    string headerValue = Request.Headers.GetValues("X-Hidden-List").FirstOrDefault(); 
    if (!string.IsNullOrEmpty(headerValue))
    {
        var results = DeserializeListAndFetch(headerValue); 
        return Ok(results); 
    }
    else
    {
        var results = ReturnEverything();
        return Ok(results);
        // or if you don't want to return everything: 
        // return BadRequest("Oops!");
    }
}

DeserializeListAndFetch(...) and ReturnEverything() would do the actual database querying.

Lerrand
  • 26
  • 3
0

You can have the array of Id in a model class and in the method parameters just accept type of that class. Like

Modal Class

Public class modal
{
      Public int[] Ids {get;set;}
}

Your Contoller

public IHttpActionResult GetAllProductsById([FromBody] modal m)
{
//Some logic with m.Ids
}

Your JSON if you are using any UI to consume this API

 {"Ids" :[1,2,3,4,5,6]}    

Hope this Helps,

  • I am more concerned about what is displayed in the URL when using `GET` method. With your suggestion, I will a URL like this: `http://localhost:1234/api/Products/GetAllProductsById?input.id=1&input.id=2`. – adjaharrison Jun 17 '17 at 08:10