Optional routing parameters with int

osyris 236 Reputation points
2021-06-01T20:10:20.683+00:00

I am trying to create a option routing action in My web-api
I keep getting a 404 error, how do I achive this web optional int

[HttpGet]
        [Route("{Title?}/{Description?}/{Pricemin?}/{Pricemax?}")]
        public async Task<List<Product>> GetFilter(
         string Title,
         string  Description,
            int PriceMin ,
            int PriceMax 
            )
        {
            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()));

            if (PriceMin > 0)
                products = products.Where(x => x.Price >= PriceMin);

            if (PriceMax > 0)
                products = products.Where(x => x.Price <= PriceMax);

            return await products.ToListAsync();
        }
Developer technologies ASP.NET ASP.NET Core
{count} votes

4 answers

Sort by: Most helpful
  1. Rena Ni - MSFT 2,066 Reputation points
    2021-06-02T03:35:41.28+00:00

    Hi @osyris ,

    I keep getting a 404 error, how do I achive this web optional int

    I guess you may use such url to send request: https://localhost:portNumber/aa///6.

    If you want to send optional data in route with specific location, you could provide the unwanted routing data with default value.

    For example, send Description and Pricemax by using url : https://localhost:portNumber/ /aa/0/6. The Title value in the first slash is white space. The Pricemin value is 0 which is the default int value.

    If you do not want to manually enter such url, you could use url rewriting and match the forward slashes amount to add white space or 0 to the url:

    https://learn.microsoft.com/en-us/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-5.0#extension-and-options


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,

    Rena

    0 comments No comments

  2. osyris 236 Reputation points
    2021-06-02T16:12:28.997+00:00

    > The URL should contain querystring parameters.

    GetFilter?Title=theTitle&Description=theDescription&Pricemin=thePricemin&Pricemax=thePricemax

    Use the FromQuery attribute to tell the Action to expect data in the URL.

    public async Task<List<Product>> GetFilter([FromQuery]
    string Title,
    string Description,
    int PriceMin ,
    int PriceMax
    )

    Keep in mind, the querystring has been around a very long time. I recommend learning HTTP GET and POST so you understand the fundamentals.

    I have done exaclty the same but i still get the 404 error
    maybe the problem is in the front-end Get method:

    my Reactjs Get Method:

       async getFilterData() {
                this.setState({ tableLoading: true });
    
    
                const   TitleFIlter = document.getElementById("TitleFIlter").value
                const   descriptionFilter = document.getElementById("DescriptionFilter").value
                const priceminFIlter = document.getElementById("PriceMin").value 
                const pricemaxFIlter = document.getElementById("PriceMax").value 
                console.log(" title =" + TitleFIlter);
                console.log("description = " + descriptionFilter);
                console.log(" PriceMin =" + priceminFIlter);
                console.log("PriceMax = " + pricemaxFIlter);
    
                const url = `api/upload/${TitleFIlter}/${descriptionFilter}/${priceminFIlter}/${pricemaxFIlter}`
                const response = await axios.get(url)
                const data = await response.data;
                this.setState({
                    allproducts: data,
                    tableLoading: false
                });
                console.log(data);
            }
    

    Please let me know if you see anything that should not be there
    I am trying to search online as well to see what im doing wrong
    but not with allot of succes, allot of codes that i see are simular as mine
    but still my code gives a 404 error anytime i dont fill in all the input parameters

    I guess you may use such url to send request: https://localhost:portNumber/aa///6.

    Thank you for you reply sir. but i would like to use the querystring url


  3. osyris 236 Reputation points
    2021-06-02T21:26:57.12+00:00

    You did not follow the instructions and format the URL as illustrated in my initial post.

    Im sorry I did not see that part.
    Once I use that url I dont longer see the 404
    but now for some reason it does not connect to the server anymore
    I have tried to send return OK(Title) to see if it responds
    and I have tried to return a Filter in the C# action it self something like this

    var allproducts = from x in _context.products
           select x;
    
        allproducts = allproducts.Where(x => x.Title.Contains("Product1"));
    
        return await allproducts.ToListAsync();
    

    there is only one "Product1" and it still returns all the products

    I have also checked if the url matches up i saw that in your example the "upload" in "api/Upload" was not with a capital
    so I have fixed that.

    still i see no response at all.


  4. osyris 236 Reputation points
    2021-06-03T14:31:26.267+00:00

    The reason why I harded coded it is because i wanted to see if it would invoke that get action at all and it did not do anyhting
    the same as with your code that i tried to invoke trough the url didnt do anything either
    I am just trying to create a simple product filter and it taking longer than a week to figure this out
    I have absoluty no qlue anymore, anything that i have tried on blog, youtubes videos, forums doesnt work.
    it is really frustrating me.

    My Full code:

       using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;
        using ReactWebshop.Models;
        using ReactWebshop.Data;
        using Microsoft.EntityFrameworkCore;
        using Microsoft.AspNetCore.Hosting;
        using System.IO;
    
        namespace ReactWebshop.Controllers
        {
            [Route("api/Upload")]
            [ApiController]
            public class ProductsController : ControllerBase
            {
                private readonly DbProductContext _context;
                private readonly IWebHostEnvironment _env;
    
                public ProductsController(DbProductContext context, IWebHostEnvironment webHostEnvironment)
                {
                    _context = context;
                    _env = webHostEnvironment;
                }
    
                [HttpPost]
                public async Task<ActionResult<Product>> PostProduct([FromForm] ProductFile productFile)
                {
    
                    if (productFile.File.Length > 0)
                    {
                        string root = _env.WebRootPath + "/img/";
                        string fileName = Guid.NewGuid().ToString() + "_" + productFile.File.FileName;
                        string Filepath = Path.Combine(root, fileName);
    
                        using (var stream = System.IO.File.Create(Filepath))
                        {
                            await productFile.File.CopyToAsync(stream);
                        }
    
    
    
                        Product newproduct = new Product()
                        {
                            Title = productFile.Title,
                            Description = productFile.Description,
                            Price = productFile.Price,
                            Quantity = productFile.Quantity,
                            FilePath = fileName
                        };
    
    
                        _context.products.Add(newproduct);
                        await _context.SaveChangesAsync();
    
    
                        return Ok("complete");
                    }
    
                    return BadRequest();
    
                }
    
    
                [HttpDelete("{id}")]
                public async Task<IActionResult> deleteproduct(int id)
                {
                    var getproduct = await _context.products.FindAsync(id);
    
                    if (getproduct == null)
                        return NotFound();
    
    
    
                    _context.products.Remove(getproduct);
                    await _context.SaveChangesAsync();
    
                    return NoContent();
    
                }
    
    
    
            [Route("{Title?}/{Description?}/{Pricemin?}/{Pricemax?}")]
                public async Task<List<Product>> GetFilter(
                    [FromQuery] string Title,
                     string Description,
                    int Pricemin,
                    int Pricemax
    
                    )
                {
                        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()));
    
                   if (Pricemin > 0)
                        products = products.Where(x => x.Price >= Pricemin);
    
                    if (Pricemax > 0)
                        products = products.Where(x => x.Price <= Pricemax);
    
    
                    return await products.ToListAsync();
                }
    
                [HttpGet]
                public async Task<IEnumerable<Product>> GetProducts()
                {
                    var allproduct = from m in _context.products
                                     select m;
    
                    return await allproduct.ToListAsync();
                }
    
    
            }
        }
    

    Reactjs

        async Getfilter1() {
    
                    const TitleFIlter = document.getElementById("TitleFIlter").value;
                    const descriptionFilter = document.getElementById("DescriptionFilter").value;
                    const priceminFIlter = document.getElementById("PriceMin").value;
                    const pricemaxFIlter = document.getElementById("PriceMax").value;
    
                    const url = `api/Upload/?Title=${TitleFIlter}&Description=${descriptionFilter}&Pricemin=${priceminFIlter}&Pricemax=${pricemaxFIlter}`;
    
                    const response = await fetch(url);
                    const data = await response.json();
                    this.setState({
                        allproducts: data,
                        tableLoading: false
                    });
    
                }
    
    
                            <div id="filtersection" style={this.state.filters ? FilterTrue : Filterfalse}>
                                <div className="FilterBloks" style={{width: "20%"}} >
                                    <label>Title:</label>
                                    <input type="text" id="TitleFIlter"  />
                                </div>
    
                                <div className="FilterBloks" style={{ width: "15%" }}>
                                    <label>Description:</label>
                                    <input type="text" id="DescriptionFilter" />
                                </div>
    
                                <div className="FilterBloks" style={{ width: "10%" }}>
                                    <label>Price min:</label>
                                    <input type="text" id="PriceMin" />
                                </div>
    
                                <div className="FilterBloks" style={{ width: "10%" }}>
                                    <label>Price max:</label>
                                    <input type="text" id="PriceMax" />
                                </div>
    
                                <div className="FilterBloks" style={{ width: "10%" }}>
                                    <label>Quantity:</label>
                                    <input type="text" id="QuantityFilter" />
                                </div>
    
                                <div className="FilterBloks" style={{ width: "20%" }}>
                                    <button className="searchButton" onClick={() => this.Getfilter1() }>Search</button>
                                </div>
                            </div>
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.