We have a controller that includes the following logic:
public class SimpleHeroBlockController : BlockComponent<SimpleHeroBlock>
protected override IViewComponentResult InvokeComponent(SimpleHeroBlock currentBlock)
var model = new SimpleHeroBlockViewModel(currentBlock);
var pageRouteHelper = ServiceLocator.Current.GetInstance<IPageRouteHelper>();
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
//var currentPage = pageRouteHelper.Page as BasePage;
var currentPage = contentRepository.Get<BasePage>(pageRouteHelper.PageLink);
We are trying to use PageRouteHelper to get hold of the page containing the block for various resons. However, the value of pageRouteHelper.Page is null and pageRouteHelper.PageLink is pointing to the block and not a page.
Are we doing something wrong here/are there any other way to get hold of the page?
What happens if you try following code:
var routeFeature = ViewComponentContext.ViewContext.HttpContext.Features.Get<IContentRouteFeature>();
var page = routeFeature?.RoutedContentData.Content as PageData;
This is basically what the default implementation of IPageRouteHelper should do under the hood as well.
I would also recommend using constructor injection of the services.
Tack Johan. Unfortunately that gave the same result. I'm still confused but now a little bit wiser. The value of pageRouteHelper.Page is actually not always null. In fact, it seems to be null under a specific condition: When editing the block in On-Page Editing mode. It thus seems to works fine when viewing the published page, editing the page in On-Page Editing mode and when editing the block in All Properties mode. Still a problem though as we have a lot of controller logic that seem to assume that pageRouteHelper.Page always holds the current page. I'm not sure, but I suspect that this issue can have been introduced when we upgraded to CMS 12 (a job that is still ongoing - including switching to constructor injections everywhere 😊).
You can probably add the IContentRouteFeature to the features collection in the controller responsible for rendering the preview of blocks.
But technically there is no page when you're previewing a shared block. You can maybe use the startpage as fallback? Or you have to make the code work without a page.
Sorry Johan, I do not understand what you mean by "add the IContentRouteFeature to the features collection". Could you please elaborate on that - if you still think it could be of value to me?I do understand if there is no page when previewing a shared block though. In this case the block is not shared, but I guess that it very well could be. However, I tested the old CMS 11 version, and there pageRouteHelper.Page seems to always have a value. Normally it is, as expected, the current page. However, when editing the block in On-Page Editing mode it is the "site page", i.e. the topmost page for the current site. Maybe this was a built in "fallback" that is no longer available in CMS 12? Anyway, a fix similar to what you suggest should thus likely do the trick 👍.
The routed page/content is stored in this feature ViewComponentContext.ViewContext.HttpContext.Features.Get<IContentRouteFeature>();. There is also a corresponding set method. So everywhere you have access to the HTTP Context, you can also access the feauturs. I assume you have a controller responsible for displaying previews of blocks, in this controller you have access to the HTTP Context and can add this feature and set the content to e.g. the start page as a fallback.