It turns out the my first mistake was to use the following command to get the root content:
var root = contentService.GetRootContent().FirstOrDefault();
This returned type IContent rather than IPublishedContent and it was downhill from there because IContent did not have the methods I needed. Furthermore this pitfall is called out explicitly at https://our.umbraco.com/Documentation/Implementation/Services/ as follows:
Although there is a management Service named the ContentService - only use this to modify content - do not use the ContentService in a View/Template to pull back data to display, this will make requests to the database and be slow - here instead use the generically named UmbracoHelper to access the PublishedContentQuery methods that operate against a cache of published content items, and are significantly quicker.
Thanks to your response I identified this issue and then with some further work solved as follows:
I injected UmbracoContext
public class BillingController : RenderMvcController
{
public UmbracoContext CatalogContext => ObjectFactory.Instance.Resolve<UmbracoContext>();
/........
}
This is not based on any sample code so I do not know if it is correct, but it satisfies the compiler and I have a more than a thousand errors to resolve in upgrading to Umbraco 8 and Ucommerce 9 before I can test :-)
Then I was able to use code similar to my original code as follows:
var root = UmbracoContext.PublishedRequest.PublishedContent.Ancestors().Where(node => node.Name == "Home").FirstOrDefault();
var address = root.Descendants("billing").FirstOrDefault();
var nextUrl = address.Url;
Key thing in your example above you are inheriting from RenderMvcController which automatically gives you reference to the UmbracoHelper and UmbracoContext, and the information you seem to be after, without needing to inject the context!
public class FlamController : RenderMvcController
{
public override ActionResult Index(ContentModel model)
{
//RenderMVCController has a static 'UmbracoContext' property
var homePage = UmbracoContext.Content.GetAtRoot().FirstOrDefault();
// the ubiquitous UmbracoHelper is always available in a controller inheriting from RenderMvcController
var queryRoot = Umbraco.ContentAtRoot().FirstOrDefault();
// when hijacking a route Umbraco passes in a 'ContentModel' containing the current IPublishedContent item
var currentIPublishedContentItem = model.Content;
// but also, you can read the AssignedContentItem from the Umbraco Helper...
var currentUmbracoItem = Umbraco.AssignedContentItem;
return CurrentTemplate(model);
}
}
Also as you coming to this with fresh eyes, if you spot things that should be updated in the docs - create an issue on the Docs repo: https://github.com/umbraco/UmbracoDocs so it can be updated to be clearer for people taking on this kind of migration task!
Descendants in Umbraco 8
In Umbraco 7 I could use the following code:
Where root is of type IPublished Content.
The best I could do in Umbraco 8 to do this is the following
First Inject a Scope Provider as follows:
And then replace the Umbraco 7 line of code with the following:
That seems to be an awful lot of somewhat complex code to replace a single simple line.
Am I missing something ? Is there a simpler approach ?
Terry Clancy ClanceZ
Hi Terry
There does appear to be some 'Descendants' extension methods for IPublishedContent in V8:
https://github.com/umbraco/Umbraco-CMS/blob/0886ada39c4651fcd0a8bec5bce4358972791c45/src/Umbraco.Web/PublishedContentExtensions.cs#L869
Do you need the
@using Umbraco.Web
namespace reference in your view/code to be able to discover them?
regards
Marc
Marc,
Wow, thanks you saved me a lot of time.
It turns out the my first mistake was to use the following command to get the root content:
var root = contentService.GetRootContent().FirstOrDefault();
This returned type IContent rather than IPublishedContent and it was downhill from there because IContent did not have the methods I needed. Furthermore this pitfall is called out explicitly at https://our.umbraco.com/Documentation/Implementation/Services/ as follows:
Although there is a management Service named the ContentService - only use this to modify content - do not use the ContentService in a View/Template to pull back data to display, this will make requests to the database and be slow - here instead use the generically named UmbracoHelper to access the PublishedContentQuery methods that operate against a cache of published content items, and are significantly quicker.
Thanks to your response I identified this issue and then with some further work solved as follows:
I injected UmbracoContext
This is not based on any sample code so I do not know if it is correct, but it satisfies the compiler and I have a more than a thousand errors to resolve in upgrading to Umbraco 8 and Ucommerce 9 before I can test :-)
Then I was able to use code similar to my original code as follows:
Again thanks for you assistance and all the best.
Terry Clancy ClanceZ
Hi Terry
This page in the docs is really helpful for understanding how to access the UmbracoContext in different scenarios:
https://our.umbraco.com/documentation/Implementation/Services/#accessing-core-services-and-helpers-in-a-controller
Key thing in your example above you are inheriting from RenderMvcController which automatically gives you reference to the UmbracoHelper and UmbracoContext, and the information you seem to be after, without needing to inject the context!
Also as you coming to this with fresh eyes, if you spot things that should be updated in the docs - create an issue on the Docs repo: https://github.com/umbraco/UmbracoDocs so it can be updated to be clearer for people taking on this kind of migration task!
regards
Marc
is working on a reply...