IgnoreRoute with webservice - Exclude asmx URLs from routing - asp.net

Im adding the filevistacontrol to my asp.net MVC web application.
I have a media.aspx page that is ignored in the routing with
routes.IgnoreRoute("media.aspx");
This works successfully and serves a standard webforms page.
Upon adding the filevistacontrol, I can't seem to ignore any calls the control makes to it's webservice.
Eg the following ignoreRoute still seems to get picked up by the MvcHandler.
routes.IgnoreRoute("FileVistaControl/filevista.asmx/GetLanguageFile/");
The exception thrown is:
'The RouteData must contain an item named 'controller' with a non-empty string value'
Thanks in advance.

Short answer:
routes.IgnoreRoute( "{*url}", new { url = #".*\.asmx(/.*)?" } );
Long answer:
If your service can be in any level of a path, none of these options will work for all possible .asmx services:
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");
routes.IgnoreRoute("{directory}/{resource}.asmx/{*pathInfo}");
By default, the parameters in a route pattern will match until they find a slash.
If the parameter starts with a star *, like pathInfo in those answers, it will match everything, including slashes.
So:
the first answer will only work for .asmx services in the root path, becasuse {resource} will not match slashes. (Would work for something like http://example.com/weather.asmx/forecast)
the second one will only work for .asmx services which are one level away from the root.{directory} will match the first segment of the path, and {resource} the name of the service. (Would work for something like http://example.com/services/weather.asmx/forecast)
None would work for http://example.com/services/weather/weather.asmx/forecast)
The solution is using another overload of the IgnoreRoute method which allows to specify constraints. Using this solution you can use a simple pattern which matches all the url, like this: {*url}. Then you only have to set a constraint which checks that this url refers to a .asmx service. This constraint can be expressed with a regex like this: .*\.asmx(/.*)?. This regex matches any string which ends with .asmx optionally followed by an slash and any number of characters after it.
So, the final answer is this:
routes.IgnoreRoute( "{*url}", new { url = #".*\.asmx(/.*)?" } );

I got it to work using this (a combo of other answers):
routes.IgnoreRoute("{directory}/{resource}.asmx/{*pathInfo}");

What happens when you use:
routes.IgnoreRoute("FileVistaControl/filevista.asmx");
If that doesn't work, try using the ASP.NET Routing Debugger to help you:
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

Try this:
routes.IgnoreRoute("{*filevista}", new { filevista = #"(.*/)?filevista.asmx(/.*)?" });
This is based on a Phil Haack recommendation stated here.

Have you tried:
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");

It would help if you posted the source for your route configuration. I'm going to take a shot in the dark and say to make sure that your IgnoreRoute() calls are all at the top of your routing definition.
The way IgnoreRoute works is to create a route that matches the ignored route URL and constraints, and attaches a StopRoutingHandler as the RouteHandler. The UrlRoutingModule knows that a StopRoutingHandler means it shouldn't route the request.
As we know, the routes are matched in the order of which they are defined. So, if your {controller}/{action}/{id} route appears before your "FileVistaControl/filevista.asmx/GetLanguageFile/" route, then it will match the "{controller}/{action}/{id}" route.
I may be totally off base here, but it's hard to know without seeing your source. Hope this helps. And post source code! You'll get better answers.

Related

Symfony2 GenerateURL to a complex route

This seems like the dumbest question ever, but I can't seem to figure it out. I have a page the needs to redirect to a complex route and I can't seem to generate the URL. Redirecting to a simple route is easy enough:
return $this->redirect($this->generateUrl('testnumber'));
However, I want to route to: testnumber/1/question/4. How can I accomplish this incredibly simple task? The only thing I have found in the documentation and Google allows me to add parameters and not just create a complex route. For example:
generateURL('testnumber', array('testid'=>1, 'question'=>4))
makes a URL of /testnumber?testid=1&question=4, which I do not want.
Edit: Yes, I already have the route created in a YML file. I simply cannot generate the URL to link to it.
return $this->redirect($this->generateUrl(???????????),true));
This is my route:
#Route("/testnumber/{testid}/question/{question}", name="testnumber")
The Symfony documentation only shows how to generate a URL to " testnumber/1", I need to generate "testnumber/1/question/4".
For
generateURL('testnumber', array('testid'=>1, 'question'=>4))
to work as you want, your route must look like (example using annotations)
#Route("/testnumber/{testid}/question/{question}", name="testnumber")
If you don't define "testid" & "question" parameters in your route, they'll be added to the query string (appended at the end of the URL as GET paramaters)
generated_route?test_id=X&question=X
Find here more relevent examples.

IIS 7 URL rewrite on WCF Service

Question Edited for better understanding:
I have a WCF service and any of my links look like :
https://192.168.1.31/ContactLibrary2.0HTTPS/Service.svc/..... .
I want to get rid of the Service.svc. I installed URL Writer in IIS but i don't know how to work with it. I search a little bit and didn't find anything to help me with this particular problem.
Any idea ?
Assuming you are configuring the application hosted at /ContactLibrary2.0HTTPS directly (and not the website containing that directory, for example), you may add an exact match for:
rest/GetContact
with a rewrite url of:
Service.svc/rest/GetContact
Perhaps you wish to rewrite every action of Service.svc, however; then you would need a regular expression match for:
^rest/.*$
with a rewrite url of:
Service.svc/{R:0}
UPDATE
Assuming you also need to remove that string from the urls of your HTML pages, you would need to couple the aforementioned inbound rule with a new outbound rule, applied to the files you are interested in.
To do that, please:
add a new outbound rule to your website and give it a name;
add a new precondition with two rules (matching any of them):
{RESPONSE_CONTENT_TYPE} matches text/html
{RESPONSE_CONTENT_TYPE} matches application/xhtml+xmll
configure the rule to match the response scope, matching the content within A tags:
should match the pattern using a regular expression;
with this pattern: ^(.*)(/Service\.svc/)(.*)$
case insensitive;
configure the action to be a rewrite, with this value: {R:1}{R:3}

ASP.NET routing: Literal sub-segment between tokens, and route values with a character from the literal sub-segment

The reason I'm asking is because IIS protects certain ASP.NET folders, like Bin, App_Data, App_Code, etc. Even if the URL does not map to an actual file system folder IIS rejects a URL with a path segment equal to one of the mentioned names.
This means I cannot have a route like this:
{controller}/{action}/{id}
... where id can be any string e.g.
Catalog/Product/Bin
So, instead of disabling this security measure I'm willing to change the route, using a suffix before the id, like these:
{controller}/{action}_{id} // e.g. Catalog/Product_Bin
{controller}/{action}/_{id} // e.g. Catalog/Product/_Bin
But these routes won't work if the id contains the new delimeter, _ in this case, e.g.
// These URL won't work (I get 404 response)
Catalog/Product_Bin_
Catalog/Product/_Bin_
Catalog/Product/__Bin
Why? I don't know, looks like a bug to me. How can I make these routes work, where id can be any string?
Ok, I have a definitive answer. Yes, this is a bug. However, at this point I regret to say we have no plans to fix it for a couple of reasons:
It's a breaking change and could be a very hard to notice one at that.
There's an easy workaround.
What you can do is change the URL to not have the underscore:
{controller}/{action}/_{id}
Then add a route constraint that requires that the ID parameter starts with an underscore character.
Then within your action method you trim off the underscore prefix from the id parameter. You could even write an action filter to do this for you if you liked. Sorry for the inconvenience.
You can use characters that are not allowed for a directory or file name like: *,?,:,",<,>,|.
With ASP.NET MVC if you look at the source they have a hard-coded value for the path separator (/) and to my knowledge cannot be changed.

ASP.NET webforms wildcard route

I'm using asp.net routing in a webforms app.
I would like to achieve the following url format:
http://[domain]/{parent-category}/{sub-category}/{sub-category}
where the right most category is available as a route value.
Currently I have achieved this with the following route:
routes.MapPageRoute(
"category-browse",
"{*category}",
"~/category.aspx"
);
This will pass all of the categories i.e. "trainers/running/nike-running-trainers" so I can grab the last one with a bit of string manipulation.
Is there a better way of doing this?
I assume you can have an arbitrary number of sub-category parameters. If that's the case, the approach you're doing is the right one. ASP.NET Routing doesn't support having a catch-all parameter in the middle of the URL. It must be at the end. So what you described is the only way to do it short of writing your own custom RouteBase implementation.

Can someone explain asp.net routing syntax to me?

I am dealing with this code in a Web Forms scenario:
public static void RegisterRoutes(RouteCollection routes)
{
Route r = new Route("{*url}", new MyRouteHandler());
routes.Add(r);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.gif/{*pathInfo}");
}
Firstly, can anyone tell me where the defintion of {*pathInfo} is?
http://msdn.microsoft.com/en-us/library/cc668201.aspx#url_patterns doesn't really define it. Does:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Match
/c/xyz.axd and
/b/c/xyz.axd and
/a/b/c/xyz.axd
Whereas
routes.IgnoreRoute("{resource}.axd");
Only matches
/xyz.axd
Secondly, in:
{*url}
What does * mean? And what does the expression as a whole mean. Is there somewhere this is clearly explained?
Thirdly, is there a particular order I need to add these expressions to correctly ignore routes? I know {*url} is some kind of catchall, should the IgnoreRoutes come before or after it eg
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.gif/{*pathInfo}");
Route r = new Route("{*url}", new MyRouteHandler());
routes.Add(r);
My 2 cents:
A route is not regex. It is simply variable and static components that make up a route, separated by segments (identified by a slash). There's one special symbol, the asterisk in the last variable, which means from here on, ignore the segment-separator -- the slash. So,
{*url}
is the simplest route, because it means take the entire URL, put it into the variable 'url', and pass that to the page associated with that route.
{controller}/{action}/{id}
puts everything in the first segment -- up to the first slash -- into the variable 'controller', puts everything between the first and second / into the variable 'action', and everything between the second and third slash (or the end) into the variable 'id'. those variables are then passed into the associated page.
{resource}.axd/{*pathInfo}
here, put the info before .axd/ (and it can't have any slashes!) into 'resource', and put everything after the first / into 'pathInfo'. Since this is typically an ignoreRoute, so instead of passing it to the page associated, it is handled by the StopHandler, which means that routing won't deal with it, and it is instead handled by the non-routing HttpHandler.
As bleevo says, routes are executed in order they're added to the collection. so IgnoreRoute s have to be added before the generic route is handled.
Here's the horse's mouth: http://msdn.microsoft.com/en-us/library/cc668201.aspx
Specific to your example, I would put the IgnoreRoute lines above your Route addition, because your route is effectively a catch-all. Also, remember that the .gif ignore will only be honoured if the gif is in the root directory.
pathinfo is just a label for a bucket. So for instance {*pathinfo} says put everything after {resource}.axd/ into pathinfo.
The routes are executing in the order you place them in the routes table, so if your very first route is a catch all the rest will never execute.

Resources