Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Remko 118 posts 283 karma points
    Mar 11, 2019 @ 11:16
    Remko
    0

    v8 - UmbracoHelper, easy way to create instance?

    In our code we were using this a lot in v7:

    UmbracoHelper umbraco = new UmbracoHelper(UmbracoContext.Current);
    IPublishedContent node = umbraco.Content(nodeId);
    

    But for v8 I cannot find any documentation on how to do this the new way. I just want to grab a node as IPublishedContent in back-end code...

    Can anyone help me with this?

  • louisjrdev 107 posts 344 karma points c-trib
    Mar 11, 2019 @ 11:39
    louisjrdev
    0

    I think this should all be using Dependency Injection now, but there is a static method on the Current object (you may need to add a reference):

    using Umbraco.Web.Composing;    
    
    Current.UmbracoHelper
    Current.UmbracoContext
    

    This may not be the 100% spot on syntax but there is definitely a way of accessing an umbraco helper on this object.

    the umbraco context can be called in a similar way.

    I will update this with the actual code when i am back at my PC

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Mar 11, 2019 @ 12:01
    Sebastiaan Janssen
    2

    But please don't use Current - in most places you will use this kind of code (like an API controller, or a SurfaceController, etc). you can just access these things already:

    IPublishedContent node = this.UmbracoContext.ContentCache.GetById(1234);

    If that's not available you can almost always get the UmbracoContext through dependency injection, I wrote a bit more about that over here:

    https://our.umbraco.com/forum/umbraco-8/96125-custom-application-started-events#comment-304012

    Happy to look at some code if you can't figure it out!

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Mar 11, 2019 @ 13:12
    Sebastiaan Janssen
    1

    Ah.. it's even easier, if you're using any of our base classes like SurfaceController etc. then you just do:

    IPublishedContent content = Umbraco.Content(1234);
    
  • Remko 118 posts 283 karma points
    Mar 13, 2019 @ 14:31
    Remko
    0

    @Sebastiaan, IContentService as parameter for constructor seems to work, but when adding UmbracoHelper to constructor the magical dependency injection doesn't seem to work ("Boot failed")

    Is there any way to get UmbracoHelper available in IComponent ?

    enter image description here

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Mar 13, 2019 @ 15:13
    Sebastiaan Janssen
    103

    @Remko - I understand from Stephane that you're not actually meant to try to get an UmbracoHelper in an IComponent, so the question is: what do you need it for?

    I'm guessing the most common scenario would be to query some content, in which case you can inject IUmbracoContextFactory and get an umbracoContext from it, the safe way to do that (in case the context does not exist yet) is to Ensure it exists first:

        private readonly IContentService _contentService;
        private readonly IUmbracoContextFactory _context;
    
        public MyComponent(IContentService contentService, IUmbracoContextFactory context)
        {
            _contentService = contentService;
            _context = context;
        }
    
        public void Initialize()
        {
            using (var cref = _context.EnsureUmbracoContext())
            {
                var cache = cref.UmbracoContext.ContentCache;
                var node = cache.GetById(1234);
            }
    
  • Ben Palmer 180 posts 866 karma points c-trib
    Apr 16, 2019 @ 21:03
    Ben Palmer
    0

    I'm also looking to get an instance of UmbracoHelper, but in a custom service.

    The reason for me, which means I can't use the content cache, is that I need to get the current page. Usually, I would get AssignedContentItem from the Umbraco helper.

    Is there another way to get the current page?

  • Marc Love (uSkinned.net) 447 posts 1789 karma points
    Oct 03, 2019 @ 10:12
    Marc Love (uSkinned.net)
    0

    I need to get access to UmbracoHelper within a class which inherits from PropertyValueConverterBase.

    The reason is to access GetDictionaryValue.

    Following the dependency injection approach I cannot inject UmbracoHelper into my class constructor.

    This crashes Umbraco with error:

    Boot failed: Umbraco cannot run. See Umbraco's log file for more details.

    -> Umbraco.Core.Exceptions.BootFailedException: Boot failed.
    
    -> System.NullReferenceException: Object reference not set to an instance of an object.
      at Umbraco.Web.Runtime.WebInitialComposer.<>c.<Compose>b__0_6(IFactory factory) in d:\a\1\s\src\Umbraco.Web\Runtime\WebInitialComposer.cs:line 116
      at DynamicMethod(Object[] )
    

    Anyone know how to get access to UmbracoHelper or Dictionary values from my PropertyValueConverter class?

    Cheers,

    Marc

  • Dan 65 posts 209 karma points
    Nov 30, 2020 @ 16:06
    Dan
    0

    Hi Mark did you ever find a solution to this im in the same situation right now :D

  • Malka Genzer 12 posts 84 karma points
    Jan 07, 2021 @ 16:02
    Malka Genzer
    0

    Did anyone find a solution? (specifically, I need to access the GetDictionaryValue from an IComponent)

  • Bo Jacobsen 606 posts 2404 karma points
    Jan 07, 2021 @ 21:22
    Bo Jacobsen
    1

    Hi Marc and Dan.

    You should be able to do this. If you find a better way please let me know :)

    i started another thread here https://our.umbraco.com/forum/using-umbraco-and-getting-started/104655-inject-custom-service-into-custom-dataannotation

    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco.Core.PropertyEditors;
    using Umbraco.Core.Models.PublishedContent;
    
    public class CustomPropertyConverter : PropertyValueConverterBase
    {
        public override object ConvertSourceToIntermediate(IPublishedElement owner, IPublishedPropertyType propertyType, object source, bool preview)
        {
            try
            {
                var localizationService = Current.Factory.GetInstance<ILocalizationService>();
                var dictionaryItem = localizationService.GetDictionaryItemByKey("Key");
                return dictionaryItem.Translations.SingleOrDefault(x => x.Language.IsoCode.Equals("isoCode"));
            }
            catch
            {
                return null;
            }
        }
    
        // Simplyfied
    }
    

    Malka you can inject ILocalizationService in a IComponent constructor.

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Jan 07, 2021 @ 18:58
    Marc Goodson
    0

    Hi Malka

    If you have a look at the way UmbracoHelper accesses the Dictionary, in GetDictionaryValue

    https://github.com/umbraco/Umbraco-CMS/blob/v8/contrib/src/Umbraco.Web/UmbracoHelper.cs#L214

    You can see it's just a wrapper for an ICultureDictionary object

     public string GetDictionaryValue(string key)
            {
                return CultureDictionary[key];
            }
    

    The CultureDictionary seems to be created by a 'CultureDictionaryFactory'

    public ICultureDictionary CultureDictionary => cultureDictionary ?? (cultureDictionary = _cultureDictionaryFactory.CreateDictionary());

    which is injected into UmbracoHelper.

    So I'm wondering if you can do the same here?

    eg inject ICultureDictionaryFactory in the same way the helper does:

     public UmbracoHelper(IPublishedContent currentPage,
                ITagQuery tagQuery,
                ICultureDictionaryFactory cultureDictionary,
                IUmbracoComponentRenderer componentRenderer,
                IPublishedContentQuery publishedContentQuery,
                MembershipHelper membershipHelper)
            {
                _tagQuery = tagQuery ?? throw new ArgumentNullException(nameof(tagQuery));
                _cultureDictionaryFactory = cultureDictionary ?? throw new ArgumentNullException(nameof(cultureDictionary));
                _componentRenderer = componentRenderer ?? throw new ArgumentNullException(nameof(componentRenderer));
                _membershipHelper = membershipHelper ?? throw new ArgumentNullException(nameof(membershipHelper));
                _publishedContentQuery = publishedContentQuery ?? throw new ArgumentNullException(nameof(publishedContentQuery));
                _currentPage = currentPage;
            }
    

    But apologies as I'm not at a pc at the moment, so this is a bit of a guess!

    (UmbracoHelper has tons of stuff in it, which requires the existance of an UmbracoContext to work, which is why it blows up when you try to inject it in a non httprequest thread - but if you inject 'just what you need' then often you are ok!)

    regards

    Marc

Please Sign in or register to post replies

Write your reply to:

Draft