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):
Assuming you have an API endpoint like so:
[Route("orders/{date}/customers")]
public HttpResponseMessage Get(string date)
{
}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>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
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
Set Item Focus in Listview Wpf
How to Print a Text File on Thermal Printer Using Printdocument
C# - How to Detect a Windows Shutdown/Logoff and Cancel That Action (After Asking the User)
C# Covariance on Subclass Return Types
Is the Sorting Algorithm Used by .Net's 'Array.Sort()' Method a Stable Algorithm
Draw Multiple Freehand Polyline or Curve Drawing - Adding Undo Feature
What's the Least Invasive Way to Read a Locked File in C# (Perhaps in Unsafe Mode)
Troubles Implementing Ienumerable<T>
Why Doesn't the C# Ternary Operator Work with Delegates
The 'Await' Operator Can Only Be Used Within an Async Lambda Expression
Using Sse in C# Is It Possible
How to Insert Characters to a File Using C#
Multicast Delegate of Type Func (With Return Value)
C#: Cast to Generic Interface with Base Type
Oracle Parameters with in Statement
How to Set Chrome Preferences Using Selenium Webdriver .Net Binding