1

I'm learning asp.net MVC and confused by this part.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

Every article, including What is routes.IgnoreRoute("{resource}.axd/{*pathInfo}"), says the same thing, "this code is to ignore requests to axd files."

If I change the code to

routes.IgnoreRoute("{x}.axd/{*y}");

does it still work?

Do the things in curly brackets matter?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Gqqnbig
  • 5,845
  • 10
  • 45
  • 86

2 Answers2

4

Yes, routes.IgnoreRoute("{x}.axd/{*y}") will still work.

Placeholder - {placeholderName}

The values within curly brackets are known as placeholders. These are simply variables and can be named whatever you want. When evaluating incoming URLs, the names don't matter at all. But when generating URLs or working out action method parameters or model property values, those names must match.

In the case of IgnoreRoute, there are no URLs generated, so those names are basically syntactic surgar.

Catch-All Placeholder - {*placeholderName}

The asterisk * indicates a catch-all placeholder. It is basically saying "match the URL, even if the rest of the segments from here to the end of the URL doesn't match the incoming URL".

Forward Slash - /

When using a catch-all placeholder as in this example, it indicates 1 or more optional segments. Since these segments are optional, so too is the right-most /. This is the same behavior when using the Default route:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

When the right-most segment is optional and it is not supplied in the URL (Home/About), this makes the right-most slash / optional as well. If the next right-most segment is also optional and omitted, the next right-most / is also optional. This explains why the default route matches the home page / instead of requiring // in order to match.

This behavior is special and only applicable to /. If you have placeholders with a different delimiter, such as {foo}-{bar} and bar is marked UrlParameter.Optional, - is still required (in fact, {bar} is required as well). /1-2 matches, /1- and /1 do not match.

Query String - ?key=value&key2=value2

Query string parameters are ignored completely when matching incoming routes. The reason why query string values are provided to MVC's ModelBinder and as action method parameters are because they are processed by value providers later on in the request.

On the other hand, when generating URLs (such as for ActionLink), any left over non-matching route values that are supplied (either in the request or directly) are added to the end of the generated URL as query string parameters.

@Html.ActionLink("Link", "Home", "About", new { key = "value", key2 = "value2" }, null)

Assuming the Default route, this ActionLink will generate the URL

/Home/About?key=value&key2=value2
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • If my url is `http://server/application/WebResource.axd?d=...`, does the slash in "{resource}.axd/{*pathInfo}" match anything? Can you explain the matching? – Gqqnbig Jan 22 '18 at 01:30
1

The 'things' in the curly brackets matter when the route is mapped onto an Action (=method) in a Controller (=class). The names specified between the curly brackets map onto the action's parameters like so:

Account/{action}/{id}/{timestamp}

Will parameterise the following function:

public IActionResult Home(int id, DateTime timestamp) { ...

The asterisk * indicates that zero-or-many (like in RegEx) path segments can occur after that. For example /a/b/c/d/e/....

Gigabyte
  • 571
  • 6
  • 14
  • ok.. If a url is `http://server/application/WebResource.axd?d=...`, will it match the pattern? I mean there is a question mark after "axd", while in the pattern it is slash after "axd". – Gqqnbig Jan 21 '18 at 20:32
  • The query string may be mapped onto the url. As in my example above, the URL `/Account/Home/123?timestamp=...` would still match the parameters in the template. For the `pathInfo` this gets ignored as it will catch everything. – Gigabyte Jan 21 '18 at 20:34
  • 1
    Routing ignores query strings completely when matching incoming requests, so it will match whether the URL has query string value or not. – NightOwl888 Jan 21 '18 at 20:37
  • @NightOwl888 it doesn't ignore them completely. The query string is part of the last segment and is picked up by the model binder later on. As demonstrated [here](http://www.emadashi.com/2012/01/querystring-in-routing-and-model-binding-in-asp-net-mvc/) – Gigabyte Jan 21 '18 at 20:40
  • 2
    Yes, but that has nothing to do with routing. It does that because of [value providers](https://stackoverflow.com/a/36606015). Routing *only* evaluates the path of the URL unless it is customized. – NightOwl888 Jan 21 '18 at 20:44
  • Am I right that the slash before the catch-all parameter doesn't have to be matched? – Gqqnbig Jan 22 '18 at 01:20