Route Parameter with Slash "/" in Url

Route parameter with slash / in URL

@bet.. I think the genericUriParserOptions is no longer applicable to .net 4.5 or later..

Also as suggested by @JotaBe, you might need to correctly decode the url request. In most case the %2F will be automatically translated to a slash '/'. So if you need to escape it you will need to decode the '%' char in the first place.. so your URL: will look something like: www.domain.com/api/orders/23%252F06%252F2015/customers

Notice the characters '%252F' will be translated to the actual '%2F'

EDIT

Ok here is the complete solution (Tried it and working for me):

  1. Assuming you have an API endpoint like so:

    [Route("orders/{date}/customers")]
    public HttpResponseMessage Get(string date)
    {
    }
  2. In the web.config you will need to set the requestPathInvalidCharacters to empty which tells the asp.net to allow all request

    <system.web>
    <httpRuntime targetFramework="4.5" requestPathInvalidCharacters=""/>
    </system.web>
    <system.webServer>
    <security>
    <requestFiltering allowDoubleEscaping="true" />
    </security>
    </system.webServer>
  3. When the client sending the request to the API you will need to make sure to escape the '%' like so:

    www.domain.com/api/orders/23%252F06%252F2015/customers

  4. You then need to decode the request

    [Route("orders/{date}/customers")]
    public HttpResponseMessage Get(string date)
    {
    DateTime actualDate = DateTime.Parse(System.Net.WebUtility.UrlDecode(date)); // date is 23/06/2015
    }

How to pass a string containing slash ('/') as parameter to a route in vue.js

You have to encode the url with javascript function encodeURIComponent(uri)

Update your router-link

<router-link :to="'/my-route/'+encodeURIComponent(myParam)">Link text</router-link>

How to define a Laravel route with a parameter that contains a slash character

Add the below catch-all route to the bottom of your routes.php and remember to run composer dump-autoload afterwards. Notice the use of "->where" that specifies the possible content of params, enabling you to use a param containing a slash.

//routes.php
Route::get('view/{slashData?}', 'ExampleController@getData')
->where('slashData', '(.*)');

And than in your controller you just handle the data as you'd normally do (like it didnt contain the slash).

//controller 
class ExampleController extends BaseController {

public function getData($slashData = null)
{
if($slashData)
{
//do stuff
}
}

}

This should work for you.

Additionally, here you have detailed Laravel docs on route parameters: [ docs ]

slashes in url variables

You need to escape the slashes as %2F.

URLs with slash in parameter?

You could use a catchall route to capture everything that follows the wiki part of the url into the id token:

routes.MapRoute(
"Wiki",
"wiki/{*id}",
new { controller = "Wiki", action = "DbLookup", id = UrlParameter.Optional }
);

Now if you have the following request: /wiki/AS/400 it will map to the following action on the Wiki controller:

public ActionResult DbLookup(string id)
{
// id will equal AS/400 here
...
}

As far as /wiki// is concerned I believe you will get a 400 Bad Request error from the web server before this request ever reaches the ASP.NET pipeline. You may checkout the following blog post.

Angular forward slash in wildcard route

Stackblitz demo

Instead of using the path attribute in your routes, you can use the poorly documented matcher attribute (check it on the docs). You probably haven't heard of it because it's not that common. But basically you provide a function that takes the paths segments (actually, an array of UrlSegment => each UrlSegment contains a path attribute referring to an element of the array produced by path.split('/')). If the matcher function returns null, it means that you haven't found a match. If it returns the array of path segments, it means it's a match.

So, you can define your matcher as:

// matches /shop/{path}/{productName}-p{product}
export function productMatcher(url: UrlSegment[]) {
// The path must start with 'shop' and have more than 1 segment
if(!url || url.length < 2 || url[0] !== 'shop') {
return null;
}

// The last segment is supposedly your product
const productSegment = url[url.length - 1].path;

// The 'g' option (global search) is mandatory for the
// regex.exec(...) below to work right
const regex = /([a-zA-z0-9-]+)(-p)(\d+)$/g;

// If it doesn't match the regex, it's not a product: it's a category
if (!regex.test(productSegment)) {
return null;
}

// To the regex.exec(...) function work right, you must reset the index
// because it was messed up by regex.test(...) function
regex.lastIndex = 0;
const m: string[] = regex.exec(productSegment);

// If there are matches, m is different from null
if (m) {
const [whole, productName, _, product] = m;

const category = url
.slice(0, url.length - 1)
.map(x => x.path)
.join('/');

// Return the original segments, and add some parameters
// to be grabbed from the paramMap.
return {
consumed: url,
posParams: {
category: new UrlSegment(category, {}),
productName: new UrlSegment(productName, {}),
product: new UrlSegment(product, {})
}
};
}
return null;
}

Then, in your routes config:

const routes: Routes = [
{
matcher: productMatcher,
component: ProductComponent
}
];

And in the component:

constructor(route: ActivatedRoute) {
route.paramMap.subscribe(m => {
this.productName = m.get("productName");
this.product = m.get("product");
this.category = m.get("category");
});
}

In a similar way, you can build a matcher for the categories. Looking at the product matcher, if among its segments we find the term shop, and it's not a product, it has to be a category (at least by the conditions mentioned in the question text.

// matches /shop/{path}
export function categoryMatcher(url: UrlSegment[]) {
if(!(url && url.length && url[0].path === 'shop')) {
return null;
}

// Just '/shop'
if (url.length === 1) {
return return {
consumed: url,
posParams: {
category: new UrlSegment('', {}),
}
};
}

const lastSegmentPath = url[url.length - 1].path;

// Every category (except shop) finish with a dash followed by a
// letter different from "p" followed by one or more numbers
const categoryRegex = /(-[a-oq-zA-OQ-Z])(\d+)$/g;
if (!categoryRegex.test(lastSegmentPath)) {
return null;
}

const category = url
.map(x => x.path)
.join("/");

return {
consumed: url,
posParams: {
category: new UrlSegment(category, {}),
}
};
}

And you can add the matcher to your router configuration:

const routes: Routes = [
{
matcher: productMatcher,
component: ProductComponent
},
{
matcher: categoryMatcher,
component: CategoriesComponent
}
];

The order here doesn't matter, because both matchers verify if there's a product in the path to making a decision.

Based on the exposed above, you can do anything you want. The Stackblitz demo shows a more interesting scenario, with a lazy-loaded module, as you want. But there's nothing so different from what I discussed above.

Angular router: ignore slashes in path parameters

I don't think it is possible to do this with pathparams. It would perfectly work with queryparams tho.

You can also try to escape the slash with %2F, but I am not 100% sure how angular will take/parse this.

Keep trailing slash in route with default parameter in Symfony 5.1

According to https://symfony.com/doc/4.1/routing/optional_placeholders.html
"Routes with optional parameters at the end will not match on requests with a trailing slash (i.e. /blog/ will not match, /blog will match)."

So if you don't absolutely care about having a trailing slash, just add a defaults={"page"=1} . However if you really do... I don't see a better option than adding a second @Route with "/article/". Since your method has a default value for the parameter, it should work.

How can I pass string path param containing slash character?

Reserved characters such as , and / must be URL encoded.

  • , is encoded as %2C
  • / is encoded as %2F

Try http://ip:port/samples/2000%2C2006%2C6576%2FM982.


The RFC 3986 defines the following set of reserved characters that can be used as delimiters. Hence, they require URL encoding:

: / ? # / [ ] / @ ! $ & ' ( ) * + , ; =

Unreserved characters do not require URL encoding:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 - _ . ~

If URL encoding , is not a good alternative for you, you could consider using query parameters. Your code will be like:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getSample(@QueryParam("business") String business,
@QueryParam("year") String year,
@QueryParam("sample") String sampleId {
...
}

And your URL will be like http://ip:port/samples?business=2000&year=2006&sample=6576%2FM982.

Please note that the / still needs to be URL encoded.

URL is appending forward slash '/' before query string

This is most likely a .htaccess issue. Though I am surprised you can't still pluck out the url parameter, as it should make little difference if the / is there or not.

A typical laravel htaccess file should look like this:

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>

RewriteEngine On

# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

EDIT

Based on a discussion in the comments, it seems that a conflicting directory in the public directory called walkthrough was/is causing the trouble.

Laravel will only trim off the trailing / if there isn't a matching directory (rightly so).

There is no harm having the trailing / though.



Related Topics



Leave a reply



Submit