Routing changes in 7.5
There are some changes that have been done regarding routing and template selection in EPiServer 7.5. Here is a summary of the most significant changes.
Routing to files/media
In EPiServer 7.5 the handling of files used in content (typically handled through FileManager) have been changed from being based on VirtualPathProviders to be based on content (IContent implementations). This means files share much of the functionality like access rights, versioning etc. as other content types (as e.g. Pages, Blocks). This also means that files are routed to in the same way as e.g. pages.
Lower-Case URLs
By default in EPiServer 7.5 URL segments for content will be generated in lower-case. It is possible to allow upper case characters in URL segments by setting EPiServer.Web.UrlSegment.UseLowerCaseSegments to false.
Trailing slash
By default URLs in EPiServer is ended with a trailing slash (except for media/files). It is possible change the behavior by setting EPiServer.Web.Routing.ContentRoute.UseTrailingSlash to false.
Direct routing to Blobs
We have introduced a partial router that handles direct routing to Blob properties. You can try this by adding “/thumbnail” to any image url. I will in a later post go into Blobs in more detail.
Performance improvements
If you run SQL profiler while doing some request against a CMS 7 site you can notice some calls to a stored procedure to match for simple address. You do not be to worried over this since that stored procedure is fast but in 7.5 we have introduced a cache for this calls. Another change is that incoming routing is not using IContentLoader.GetChildren (which is the case in CMS7), instead it uses a new method IContentLoader.GetBySegment. This method is not dependent on the number of items on a certain level in the content tree, so especially when routing through a structure with many items at the same level 7.5 routes much faster. This new method is also used when generating URL segments so creating/saving content instances(especially where there are many items on the same level) is also faster.
UrlResolver
The class EPiServer.Web.UrlResolver can be used both to generate URLs for content items and also get the content item for a given URL. We have added some methods to make it easier to control the URL generation. For example it is possible to specify for which context (View, Edit, Preview) the URL should be constructed for. We have also added a static property Current to UrlResolver make it easier to use in cases where testability is not applicable/important.
Partial routing to IContent instances
Some changes have been done in the case where partial routing is used to route to IContent instances. Now the extension method RequestContext.GetContentLink() will return the link to the partial routed content instance (and not the “ordinary routed content” as in CMS7). You can however get the “ordinary routed content” that was routed to by using extension method RequestContext.GetOriginalRoutedLink().
This has the consequence that ContentRouteHelper will also give the partial routed content while PageRouteHelper will give either the partial routed content (if it is a page) or the page where partial routing took of (given that it was a page) or StartPage as final fallback.
The reason for this is that it should be possible to use for example the new base class ContentPageBase<TContent> or ContentPageBase<PageData, TContent> which then will offer both a CurrentPage and a CurrentContent. In MVC the similarity is to have two parameters currentPage and currentContent that will be assigned by the model binder.
Routing to “classic” links
Previously it was possible to make a request to a webform page with a classic link like e.g. http://localhost:17000/Templates/Page.aspx?id=17&epslanguage=en. By default this will not work anymore since the implementation of CurrentPage in PageBase does not pay attention to query parameters any more (instead it relies that the routing has set the routed content),
It is however possible to register a special route to handle “classic” links, this can be done like:
protected override void RegisterRoutes(System.Web.Routing.RouteCollection routes)
{
base.RegisterRoutes(routes);
routes.Insert(0, ServiceLocator.Current.GetInstance<ClassicLinkRoute>());
}
Template selection for on-page edit and preview
Previously when a template was selected for on-page edit the system first tried to select the default template (that is without any tag). If no such template was found a selection was done for a template with tag “Preview” (this is how on-page editing for shared blocks work).
This has been changed so now in on-page edit mode a selection is first done for a template with tag “Edit”, if no such is found a fallback is done for first default template(no tag) and finally a template with tag “Preview”. And in preview mode a selection is done for a template with tag “Preview” with fallback to default.
This makes it possible to for example have three different templates for a page, one tagged with “Edit”, one with “Preview” and one default. In most cases a “Preview” template is probably not needed but a “Edit” template can be useful. One use case is to expose properties on the “Edit” template that is not part of the normal template used in view mode. This makes it possible for editors to edit these properties directly on page without having to go to “All properties”/Forms mode.
Strict language routing
The routing has been changed so it is more strict due to language handling (partly introduced already in patches to EPiServer 7). As an example say that there is a page under start page named "News" in English and "Nyheter" in Swedish. Previously the following URLs where handled like (given that no language mapping is defined for site hosts):
- http://sitehost/News/ (page in language given by context typically globalization setting in web.config e.g. en)
- http://sitehost/en/News/ (page in english)
- http://sitehost/sv/Nyheter/ (page in swedish)
- http://sitehost/Nyheter/ (page in english since no language info in URL get language as in point 1)
- http://sitehost/en/Nyheter/ (page in english since language segment states english)
With the new strict language routing the above URLs will be handled as:
- http://sitehost/News/ (404 since when not having language-host mapping in config language segment must be present, unless site have only one language)
- http://sitehost/en/News/ (page in english)
- http://sitehost/sv/Nyheter/ (page in swedish)
- http://sitehost/Nyheter/ (404 as in 1.)
- http://sitehost/en/Nyheter/ (404 since language for page with URL segment does not match language segment).
Another change is that when a language mapping is defined for a host, say for example that host “sitehost” is mapped to “en” then an URL like http://sitehost/en/News/ will give a 404 since when there is a host mapping that defines a language then that language should not be present in URL.
There is a configuration setting "strictLanguageRouting" on configuration element applicationSettings that can be set to false to get old more tolerant behavior.
Really nice improvements. How is non latin characters handled in the url segment? Any improvements there?
There are no major changes to how URL segments are treated so it's still basically the same ASCII ruleset with a few hard coded mappings (ü => u, ö => o).
Hello Guys,
Quite liking EPiServer 7.5 improvements, for this one in particular I have one question:
Is there a way to modify the routing behavior so that the master language doesn't require the language segment. In the example above, if the master language is english:
* http://sitehost/News/ (goes to english page, because News master language is english)
* http://sitehost/en/News/ (301 to http://sitehost/News/)
* http://sitehost/sv/Nyheter/ (page in swedish)
* http://sitehost/Nyheter/ (404 cause swedish is not the master language)
* http://sitehost/en/Nyheter/ (404 due to mismatch between language segment and page-url-segment)
Cheers,
How does routing work when you have language mappings per host defined?