Search code examples
c#asp.net-coreasp.net-core-mvc.net-5asp.net5

How to create route with multiple optional string parameters in asp.net core?


I have an application that is written on the top of asp.net core 5/.Net 5 framework. I have a need to create a flexible route that would bind multiple string parameters.

for example, the route would look like this

/homes-for-sale-in-los-angeles-100/0-5000_price/condo,apartment_type/0-5_beds/0-4_baths/2_page

In the above URL the only required part will be /homes-for-sale-in-los-angeles-100. los-angeles is the city name and 100 is the id. The rest of it are just parameters. The 0-5000_price meaning I want to bind the value 0-5000 to a parameter called price.

Not always all the parameters are provided. Here are some different shapes of the same route

/homes-for-sale-in-los-angeles-100/condo,apartment_type
/homes-for-sale-in-los-angeles-100/0-5000_price/10_page
/homes-for-sale-in-los-angeles-100/condo_type/0-5000_price/2_page

Here is what I have done

[Route("/homes-for-sale-in-{city}-{id:int}.{filter?}/{page:int?}", Name = "HomesForSaleByCity")]
public async Task<IActionResult> Display(SearchViewModel viewModel)
{
    return View();
}

public class SearchViewModel 
{
    [Required]
    public int? Id { get; set; }
    
    public string City { get; set; }

    public string Price { get; set; }

    public string Type { get; set; }

    public string Beds { get; set; }

    public string Baths { get; set; }

    public int Page { get; set; }
}

How can I create a route that would allow multiple optional parameters and bind them correctly?


Solution

  • Using a route definition like this will make it capture all those routes you provided :

    [Route("homes-for-sale-in-{city}-{id}/{**catchAll}")]
    [HttpGet]
    public async Task<IActionResult> City(string city, string id, string catchAll)
    {
      // Here you will parse the catchAll and extract the parameters        
      await Task.Delay(100);
      return this.Ok(catchAll);
    }
    

    Also please note that catchAll parameter can't be made optional. So a request like /homes-for-sale-in-los-angeles-100/ will result in 404.