Asked by:
Creating a data filter in a API

Question
-
User1750806012 posted
Im not sure if this is the right approach to create a product filter system
to filter products on a page.
Reactjs:
async getFilteredProducts() { const TitleFIlter = document.getElementById("TitleFIlter").value; const descriptionFilter = document.getElementById("DescriptionFilter").value; const url = `api/upload/${TitleFIlter}/${descriptionFilter}/` const response = await axios.get(url) const data = await response.data; this.setState({ allproducts: data, }); console.log(data); }
my api:
[HttpGet("{Title}/{description}")] public async Task<List<Product>> GetFilter(string Title, string description) { IQueryable<Product> products = _context.products; if (!string.IsNullOrEmpty(Title)) products = products.Where(x => x.Title.ToLower().Contains(Title.ToLower())); if (!string.IsNullOrEmpty(description)) products = products.Where(x => x.Description.ToLower().Contains(description.ToLower())); return await products.ToListAsync(); }
with one parameter it works fine but with multiples i get a 405 error
I just want the url to appear for example:
https://www.myserver.com?titlename=apple-jacks&pricemin=12.34&pricemax=23.45
Monday, May 31, 2021 1:44 AM
All replies
-
User1686398519 posted
Hi osyris,
The 405 Method Not Allowed is an HTTP response status code indicating that the specified request HTTP method was received and recognized by the server, but the server has rejected that particular method for the requested resource.
[HttpGet("{Title}/{description}")]
The GetFilter action includes the "{Title}/{description}" template, therefore Title is appended to the "api/[controller]" template on the controller.
- The methods template is "api/[controller]/{Title}/{description}".
- Therefore this action only matches GET requests for the form
/api/controllername/value1/value2.
- value1 is the value of the parameter Title, value2 is the value of the parameter description.
- In other words, if you add [HttpGet("{Title}/{description}")], you should request it like this:
-
https://localhost:xxxxx/test/title1/hello
-
If you want to use the form of Query String(https://localhost:xxxxx/test?Title=title1&description=hello), you can remove "[HttpGet("{Title}/{description}")]".
Best Regards,
YihuiSun
Monday, May 31, 2021 9:43 AM -
User1750806012 posted
I see that when I use both paremeters (send from Reactjs ) it works perfect
but when I try to only use 1 paremeter it gives me a the error 405
How can I use a filter were I can choose wether I use all filter fields or only one,
like what a normal page filter does.
I have tried to set a default but it didnt work
[Route("{Title}/{Description}")] public async Task<List<Product>> GetFilter( [FromQuery] string Title = "", [FromQuery] string Description = "") { IQueryable<Product> products = _context.products; if (!string.IsNullOrEmpty(Title)) products = products.Where(x => x.Title.ToLower().Contains(Title.ToLower())); if (!string.IsNullOrEmpty(Description)) products = products.Where(x => x.Description.ToLower().Contains(Description.ToLower())); return await products.ToListAsync(); }
Could you write me an example or adjust the code above ?
Monday, May 31, 2021 4:28 PM -
User1750806012 posted
I also see that when I Fill in one input only 1 of the 2 parameters will show :
If fill in the TItle input only casses the 405 error:https://localhost:44340/api/upload/mobile/
when i fill in both inputs it will work fine:
https://localhost:44340/api/upload/mobile/Newest
Reactjs code that i use:
async getFilterData() { this.setState({ tableLoading: true }); let TitleFIlter = document.getElementById("TitleFIlter").value let descriptionFilter = document.getElementById("DescriptionFilter").value\ console.log(" title =" + TitleFIlter); console.log("description = " + descriptionFilter); const url = `api/upload/${TitleFIlter}/${descriptionFilter}` const response = await axios.get(url) const data = await response.data; this.setState({ allproducts: data, tableLoading: false }); console.log(data); }
Is this more of a problem from the reactjs side or Asp net core ?
what would be the best/professional solution to solve this?
Monday, May 31, 2021 11:03 PM -
User1686398519 posted
Hi osyris,
You can set the parameters in the routing template as optional parameters.
- If the parameters of the routing template itself are not set as optional, otherwise the parameters are considered necessary.
[HttpGet("{Title?}/{description?}")]
Here is the result.
Best Regards,
YihuiSun
Tuesday, June 1, 2021 1:59 AM -
User-2054057000 posted
A better approach will be to use LINQ Expression for doing filtering. It is basically like:
Task<List<T>> MyFilterAsync(Expression<Func<T, bool>> filter)
Consider seeing this tutorial - Filtering Entity by LINQ Expression
Wednesday, June 2, 2021 5:47 AM