This should work:
var url = "/my-page"; var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>(); var contentData = @urlResolver.Route(new UrlBuilder(url));
@urlResolver.Route(new UrlBuilder("/")) or @urlResolver.Route(new UrlBuilder("http://myhost/")) or @urlResolver.Route(new UrlBuilder("/my-page"))
all returns null...
I'm trying to figure out what EpiServer does to lookup the content, does it look this up in the db or mabye with some component that is not initialized..
Doesn't something like this work?
public static IContent GetCurrentContent() { ContentRouteHelper contentRouteRouteHelper = ServiceLocator.Current.GetInstance<ContentRouteHelper>(); return contentRouteRouteHelper.Content ; }
Oh, mabye I forgot to tell you :P that I'm not in the conext of a normal EpiServer request. I want to do this when a web api method executes, that doesn't have the normal EpiServer context.
I did some testing with Alloy and used the same code as Tim:
public IContent GetContent() { var url = "/alloy-plan"; var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>(); IContent contentData = urlResolver.Route(new UrlBuilder(url)); return contentData; }
This is the test code:
IContent fromSameThread = null; IContent fromNewThread = null; fromSameThread = GetContent(); Thread thread = new Thread(() => { fromNewThread = GetContent(); }); thread.Start(); thread.Join(1000);
if the wildcard is missing, fromNewThread will be set to null.
Hope this helps!
Hmm, the wild card is there, but the executing thread is in another process than the "original" setup. I will try to check the configuration setup. Thanks for your help so far! :)
@Erik - another process, meaning that webapi is hosting in different IIS app that's running under different host binding?
@Jeroen, @Tim - what is ServiceLocator??? :)
It's another process, but with connection to the same database.
I'm able to do this: DataFactory.Instance.GetPage(new PageReference(id))
And the Id is the content id e.g. 6. That works. But I cannot "reverse" lookup the page from the content url.
Well, we have a site setup running episerver. Then we've created another asp.net web api project that needs to access the same site, but it is not the same web application, does not share the same web.config and in the end, not the same process, another application pool in the iis.
Content routing is an implementation based on System.Web.Routing which means that the CMS routes must be added to the global RouteCollection. On a normal web site this is done in the Global constructor (the class inheriting HttpApplication). So if your code is running in another process you need to register the CMS routes.
Easiest is if you can change the class in your Global.asax.cs file to inherit EPiServer.Global. If not possible then you can call extension method MapContentRoute (extends RouteCollection in namespace EPiServer.Web.Routing) using the static property System.Web.Routing.RouteTable.Routes.
You can verify that CMS routes are registered by examing System.Web.Routing.RouteTable.Routes under a debugger.
@Johan, I see that SiteDefinition repository is involved - looking for site host name matching currently incoming request host name. Am I looking in wrong place?
@Vladis Your assumption about sitedefinition resoliving is correct and if there was no wildcard host defined it would be the likely cause.
Each content route that is set up is given a "root" which is the starting point for the route. So there is one route setup to handle content under startpage. So when that route evaluates the request it will first determine which site it is. During this it will look if there is a current http request and if so it will match the host from the request with the hosts definied on the different site definitions, and if some host match then that site is considered "current", if no host matches it will pick the wildcard host if any else it will get a sitedefinition without startpage (meaning the route will not match).
But since there is a site with wildcard host that host should be considered "current" in this case.
We have the wildcard host defined in the admin UI. Is there nothing you need to do in the web.config to make it work or some other initialization?.. I do not have the content "pages" implemented in the web api project where I try to resolve the url. I wonder where EpiServer inititalizes this information (route->page). I wish EpiServer was open source :) Then this would be solved in no-time :P
If you want to debug into the EPiServer code you could use e.g. dotPeek and let it generated pdb files for you and then let it act as a symbol server.
Yes I know, but I tried that with reflector but I get the "optimized away" problem.. I will give it one more go, when I get some more time to investigate.
Another thing that popped up in my head is that if the page that "/my-page" refers to is not under the same site that is holding the wildcard mapping then it will not route. Reason for this is that there is a route constraint that is run after the routing that verifies that the routed content is indeed part of the current site.
This is to prevent "cross-site" routing between sites in a multi-site scenario.
Another thing is language. Have you tried to add a language segment to the path like '/en/my-page'?
I solved it. My bad! In the Web API service I had forgot to Init Epi Server, so when adding:
Snippet
public class WebApiApplication : EPiServer.Global
and
Snippet
public override void Init() { base.Init();
It worked! Thank you for all your help!
I need to get the PageData from the friendly Url. E.g. "/my-page". I do not have the host part of the url.
I've tried:
EPiServer.Web.Routing.UrlResolver.Current.Route
PageReference.ParseUrl
PermanentLinkUtility.GetGuid
Global.UrlRewriteProvider.ConvertToInternal
Any other suggestions?