Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dash in the URL query in ASP.NET Core

Can we use dashes (-) in the Route template in ASP.NET Core?

// GET: api/customers/5/orders?active-orders=true
[Route("customers/{customer-id}/orders")]
public IActionResult GetCustomerOrders(int customerId, bool activeOrders)
{
    .
    .
    .
}

(The above code doesn't work)

like image 444
Tohid Avatar asked Oct 27 '18 14:10

Tohid


2 Answers

The route parameters usually directly map to the action's variable name, so [Route("customers/{customerId}/orders")] should work since that's the name of your variable (int customerId).

You don't need dashes there, the part within the curly braces {} will never appear as a part of the generated url, it will always be replaced by the content you pass from browser or the variables you pass to the url generator.

customers/{customerId}/orders will always be customers/1/orders when customerId is set to 1, so there's no point trying to force it to {customer-id}.

However, you can try public

[Route("customers/{customer-id}/orders")]
IActionResult GetCustomerOrders([FromRoute(Name = "customer-id")]int customerId, bool activeOrders)

to bind the customerId from a unconventional route name, if you wish. But I'd strongly advise against it, as it just adds unnecessary code which has absolutely zero-effect on your generated urls.

The above generates (and parses) the exactly same url as

[Route("customers/{customerId}/orders")]
IActionResult GetCustomerOrders(int customerId, bool activeOrders)

and is much more readable code.

For the query part, as you figured it out in the comments, it makes sense to add the dashes via [FromQuery(Name = "active-orders")] bool activeOrders, since that really affects the generated url.

New in ASP.NET Core 2.2

In ASP.NET Core 2.2 you'll get a new option to 'slugify' your routes (only supported when using the new Route Dispatcher instead of the default Mvc Router).

A route of blog\{article:slugify} will (when used with Url.Action(new { article = "MyTestArticle" })) generate blog\my-test-article as url.

Can also be used in default routes:

routes.MapRoute(
    name: "default",
    template: "{controller=Home:slugify}/{action=Index:slugify}/{id?}");

For further details see the ASP.NET Core 2.2-preview 3 annoucement.

like image 133
Tseng Avatar answered Oct 02 '22 11:10

Tseng


Just expanding on Tseng answer to the question. for ASP NET CORE to use "slugify" transformer you need to register it first like so:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        if (value == null) { return null; }

        return Regex.Replace(value.ToString(), 
                             "([a-z])([A-Z])",
                             "$1-$2",
                             RegexOptions.CultureInvariant,
                             TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
    }
}

and then in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddRouting(options =>
    {
        options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    });
}

Code from Microsoft

like image 32
Hamed Avatar answered Oct 02 '22 10:10

Hamed