Copied to clipboard

Flag this post as spam?

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


  • Adriano Fabri 469 posts 1633 karma points
    Mar 02, 2021 @ 16:02
    Adriano Fabri
    0

    How can I create a custom Members Index (or override the defaut) in Umbraco v8

    Hi to all, I'm trying to create a custom Members Index that includes custom fields.

    I write this code starting from the official guide: Umbraco Indexing Reference

    MY CUSTOM COMPOSER

    using Examine;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco.Core.Services;
    using Umbraco.Examine;
    using Umbraco.Web.Search;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Controllers
    {
        public class AFMembersIndexComposer : IUserComposer
        {
            public void Compose(Composition composition)
            {
                composition.Components().Append<AFMembersIndexComponent>();
                composition.RegisterUnique<AFMembersIndexComponent, AFMembersIndexCreator>();
            }
        }
    }
    

    MY CUSTOM COMPONENT

    using Examine;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using static Umbraco.Core.Constants;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Controllers
    {
        public class AFMembersIndexComponent : IComponent
        { 
            private readonly IExamineManager _examineManager;
            private readonly AFMembersIndexCreator _afMembersIndexCreator;
    
            public AFMembersIndexComponent(IExamineManager examineManager, AFMembersIndexCreator afMembersIndexCreator)
            {
                _examineManager = examineManager;
                _afMembersIndexCreator = afMembersIndexCreator;
            }
    
            public void Initialize()
            {
                // get the AFMembersIndex
                if (!_examineManager.TryGetIndex("AFMembersIndex", out IIndex AFMembersIndex))
                    return;
    
                // add a custom field type
                AFMembersIndex.FieldDefinitionCollection.TryAdd(new FieldDefinition("memberName", FieldDefinitionTypes.FullText));
                AFMembersIndex.FieldDefinitionCollection.TryAdd(new FieldDefinition("memberSurname", FieldDefinitionTypes.Double));
    
                // modify an existing field type (not recommended)
                //index.FieldDefinitionCollection.AddOrUpdate(new FieldDefinition("parentID", FieldDefinitionTypes.FullText));
    
                _examineManager.AddIndex(AFMembersIndex);
            }
    
            public void Terminate() { }
        }
    }
    

    MY CUSTOM CREATOR

    using System.Collections.Generic;
    using System.Linq;
    using Examine;
    using Lucene.Net.Analysis;
    using Umbraco.Core;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Services;
    using Umbraco.Examine;
    using Umbraco.Web.Search;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Controllers
    {
        public class AFMembersIndexCreator : LuceneIndexCreator, IUmbracoIndexesCreator
        {
            private readonly IProfilingLogger _profilingLogger;
            private readonly ILocalizationService _localizationService;
            private readonly IPublicAccessService _publicAccessService;
    
            // Since Umbraco 8 has dependency injection out of the box, we can use it to inject
            // the different services that we need.
            public AFMembersIndexCreator(IProfilingLogger profilingLogger, 
                                           ILocalizationService localizationService, 
                                           IPublicAccessService publicAccessService, 
                                           IMemberService memberService, 
                                           IUmbracoIndexConfig umbracoIndexConfig)
            {
                _profilingLogger = profilingLogger;
                _localizationService = localizationService;
                _publicAccessService = publicAccessService;
            }
    
            // Noticed that we return a collection of indexes? Technically you
            // can create multiple indexes in an indexCreator :) You can have a look at
            // UmbracoIndexesCreator.cs in the CMS core and see how the CMS does that.
            public override IEnumerable<IIndex> Create()
            {
                // create my AFMemberIndex definitions
                IIndex AFMemberIndex = CreateAFMemberIndex();
    
                return new[] { AFMemberIndex };
            }
    
            private IIndex CreateAFMemberIndex()
            {
                UmbracoMemberIndex AFMembersIndex = new UmbracoMemberIndex("AFMembersIndex", 
                                                    new UmbracoFieldDefinitionCollection(), 
                                                    CreateFileSystemLuceneDirectory("AFMembersIndex"),
                                                    new WhitespaceAnalyzer(), 
                                                    _profilingLogger,
                                                    new MemberValueSetValidator());
                return AFMembersIndex;
            }
        }
    }
    

    When I try to start Umbraco I receive following error after process my composer (the component and the creator aren't called): Stacktrace

    Can anyone help me? It would also be okay to override the default MemberIndex to include the custom fields

    With Umbraco 7 it was very simple to create a new Cusom Index and I never had problems...with Umbraco 8 I can't!!! :-s

    Thank you A.

  • Adriano Fabri 469 posts 1633 karma points
    Mar 02, 2021 @ 16:37
    Adriano Fabri
    0

    In the UmbracoTracelog I found this info:

    {"@t":"2021-03-02T16:28:05.5911281Z","@mt":"{FailMessage} ({Duration}ms) [Timing {TimingId}]","@l":"Error","@x":"Umbraco.Core.Exceptions.BootFailedException: Boot failed. ---> System.ArgumentOutOfRangeException: The implementing type AF.Examine.Index.Tools.For.UmbracoV8.Controllers.AFMembersIndexCreator is not assignable from AF.Examine.Index.Tools.For.UmbracoV8.Controllers.AFMembersIndexComponent.\r\nNome parametro: implementingType\r\n   in LightInject.ServiceContainer.EnsureConstructable(Type serviceType, Type implementingType)\r\n   in LightInject.ServiceContainer.RegisterService(Type serviceType, Type implementingType, ILifetime lifetime, String serviceName)\r\n   in Umbraco.Core.Composing.LightInject.LightInjectContainer.Register(Type serviceType, Type implementingType, Lifetime lifetime)\r\n   in Umbraco.Core.Composing.Composition.<>c__DisplayClass37_0.<RegisterUnique>b__0(IRegister register)\r\n   in Umbraco.Core.Composing.Composition.CreateFactory()\r\n   in Umbraco.Core.Runtime.CoreRuntime.Boot(IRegister register, DisposableTimer timer)\r\n   --- Fine della traccia dello stack dell'eccezione interna ---","FailMessage":"Boot failed.","Duration":199099,"TimingId":"e10d37d","SourceContext":"Umbraco.Core.Runtime.CoreRuntime","ProcessId":7936,"ProcessName":"iisexpress","ThreadId":1,"AppDomainId":2,"AppDomainAppId":"LMW3SVC3ROOT","MachineName":"VP-FABRI","Log4NetLevel":"ERROR","HttpRequestNumber":1,"HttpRequestId":"96c94f7c-01f1-4347-831e-fa789feb913a"}
    
  • Rodolphe Toots 35 posts 166 karma points
    Mar 03, 2021 @ 17:56
    Rodolphe Toots
    0

    Just a word of advice: To get help in an international forum, you really cant post stacktraces that are written in Italian. I can see you have a null reference somewhere, but not easy to understand that screenshot.

  • Adriano Fabri 469 posts 1633 karma points
    Mar 04, 2021 @ 11:07
    Adriano Fabri
    0

    Hi Rodolphe, I'm sorry but I configured VS2019, IIS and IIS Express in english language but I really don't know why the stack messages are still in Italian language.

    Any help about it?

  • Adriano Fabri 469 posts 1633 karma points
    Mar 04, 2021 @ 11:31
    Adriano Fabri
    0

    ok...I updated the stacktrace image with the english one.

    I forced globalization to en-US in web.config

    <system.web>
        <globalization uiCulture="en-US" culture="en-US" />
        ....
    </stsem.web
    
  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 03, 2021 @ 18:03
    Nik
    0

    Hi Adriano,

    Can you share your composer and component code please? It might be "order" you are doing things causing a null reference exception :-)

    Cheers

    Nik

  • Adriano Fabri 469 posts 1633 karma points
    Mar 04, 2021 @ 11:11
    Adriano Fabri
    0

    Hi, you can find them in main post (or I don't understand the question) :-)

    I posted:

    • my custom Composer code
    • my custom Component code
    • my custom Creator code

    Tell me if you need anything else

    A.

  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 04, 2021 @ 11:33
    Nik
    0

    Hi Adriano,

    Try swapping these two lines around:

     composition.Components().Append<AFMembersIndexComponent>();
     composition.RegisterUnique<AFMembersIndexComponent, AFMembersIndexCreator>();
    

    Basically, I think LightInject is trying to create your AFMembersIndexComponent before your AFMembersIndexGenerator is registered.

    Also this line is not right,

            composition.RegisterUnique<AFMembersIndexComponent, AFMembersIndexCreator>();
    

    Change it to:

            composition.RegisterUnique<AFMembersIndexCreator>();
    

    With those two changes, see how you get on :)

    Nik

  • Adriano Fabri 469 posts 1633 karma points
    Mar 04, 2021 @ 11:55
    Adriano Fabri
    0

    Hi Nik, If I only swap the RegisterUnique and the components.Append lines I receive the same error as above (see the main post stacktrace)

    If I follow all your indications, finally Umbraco starts but I don't see my custom Index

    No Custom Index

    A.

  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 04, 2021 @ 12:17
    Nik
    100

    I think you might be "missing" some bits.

    This is a quick overview of all the bits I've got when I create a custom index:

    Component

    internal class MyCustomIndexComponent : IComponent
    {
        private readonly IExamineManager _examineManager;
        private readonly MyCustomIndexCreator _myCustomIndexCreator;
    
        public MyCustomIndexComponent (IExamineManager examineManager, MyCustomIndexCreator myCustomIndexCreator)
        {
            _examineManager = examineManager;
            _myCustomIndexCreator = myCustomIndexCreator;
        }
    
        public void Initialize()
        {
            foreach (var index in _myCustomIndexCreator .Create())
                _examineManager.AddIndex(index);
        }
    
        public void Terminate()
        {
        }
    }
    

    Creator

    public class MyCustomIndexCreator : LuceneIndexCreator
    {
        public override IEnumerable<IIndex> Create()
        {
            var index = new LuceneIndex("MyIndexName",
                CreateFileSystemLuceneDirectory("MyIndexName"),
                new FieldDefinitionCollection(
                    new FieldDefinition("Id", FieldDefinitionTypes.FullText),
                    new FieldDefinition("Code", FieldDefinitionTypes.FullTextSortable),
                    new FieldDefinition("Name", FieldDefinitionTypes.FullText),
                    new FieldDefinition("Family", FieldDefinitionTypes.FullTextSortable),
                    new FieldDefinition("SortOrder", FieldDefinitionTypes.Integer),
                    new FieldDefinition("Details", FieldDefinitionTypes.FullText)
                ),
                new StandardAnalyzer(Version.LUCENE_30));
    
            return new[] { index };
        }
    }
    

    I've also got a Populator and ValueSetBuilder for actually putting data into the index.

    Looking at your code, it doesn't look like you are registering your creator properly.

    Does this help?

    Cheers

    Nik

  • Adriano Fabri 469 posts 1633 karma points
    Mar 04, 2021 @ 15:35
    Adriano Fabri
    1

    Hi Nik, thank you very much...you saved me :-)

    Yeah...I had to modify the creator and the composer as you told me but also I had to create the Populator and the ValueSetBuilder as well.

    So...I want to share the code to help anyone who needs it ;-)

    Thank you again.

    A.

    Composer

    using AF.Examine.Index.Tools.For.UmbracoV8.Components;
    using AF.Examine.Index.Tools.For.UmbracoV8.Creators;
    using AF.Examine.Index.Tools.For.UmbracoV8.Populators;
    using AF.Examine.Index.Tools.For.UmbracoV8.ValueSetBuilders;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Composers
    {
        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
        public class AFMembersIndexComposer : IUserComposer
        {
            public void Compose(Composition composition)
            {
                composition.RegisterUnique<AFMembersIndexValueSetBuilder>();
                composition.Register<AFMembersIndexPopulator>(Lifetime.Singleton);
                composition.RegisterUnique<AFMembersIndexCreator>();
                composition.Components().Append<AFMembersIndexComponent>();
            }
        }
    }
    

    Component

    using AF.Examine.Index.Tools.For.UmbracoV8.Creators;
    using Examine;
    using Umbraco.Core.Composing;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Components
    {
        public class AFMembersIndexComponent : IComponent
        { 
            private readonly IExamineManager _examineManager;
            private readonly AFMembersIndexCreator _afMembersIndexCreator;
    
            public AFMembersIndexComponent(IExamineManager examineManager, AFMembersIndexCreator afMembersIndexCreator)
            {
                _examineManager = examineManager;
                _afMembersIndexCreator = afMembersIndexCreator;
            }
    
            public void Initialize()
            {
                // Try get the AFMembersIndex
                if (!_examineManager.TryGetIndex("AFMembersIndex", out IIndex AFMembersIndex))
                {
                    // add AFMembersIndex to examineManager
                    foreach (var index in _afMembersIndexCreator.Create())
                        _examineManager.AddIndex(index);
                }
            }
    
            public void Terminate() { }
        }
    }
    

    Creator

    using Examine;
    using Examine.LuceneEngine.Providers;
    using Lucene.Net.Analysis.Standard;
    using Lucene.Net.Util;
    using System.Collections.Generic;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Services;
    using Umbraco.Examine;
    using Umbraco.Web.Search;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Creators
    {
        public class AFMembersIndexCreator : LuceneIndexCreator, IUmbracoIndexesCreator
        {
            private readonly IProfilingLogger _profilingLogger;
            private readonly ILocalizationService _localizationService;
            private readonly IPublicAccessService _publicAccessService;
    
            // Since Umbraco 8 has dependency injection out of the box, we can use it to inject
            // the different services that we need.
            public AFMembersIndexCreator(IProfilingLogger profilingLogger, 
                                            ILocalizationService localizationService, 
                                            IPublicAccessService publicAccessService, 
                                            IMemberService memberService, 
                                            IUmbracoIndexConfig umbracoIndexConfig)
            {
                _profilingLogger = profilingLogger;
                _localizationService = localizationService;
                _publicAccessService = publicAccessService;
            }
    
            // Noticed that we return a collection of indexes? Technically you
            // can create multiple indexes in an indexCreator :) You can have a look at
            // UmbracoIndexesCreator.cs in the CMS core and see how the CMS does that.
            public override IEnumerable<IIndex> Create()
            {
                // create my AFMemberIndex definitions
                return new[] { CreateAFMemberIndex() };
            }
    
            private IIndex CreateAFMemberIndex()
            {
                var AFMembersIndex = new LuceneIndex("AFMembersIndex",
                                                       CreateFileSystemLuceneDirectory("AFMembersIndex"),
                                                       new FieldDefinitionCollection(
                                                            new FieldDefinition("memberId", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberNodeName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberLoginName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberEmail", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberSurname", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberIntTel", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberFax", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberCel", FieldDefinitionTypes.FullText),
                                                       ),
                                                       new StandardAnalyzer(Version.LUCENE_30));
    
                return AFMembersIndex;
            }
        }
    }
    

    Populator

    using AF.Examine.Index.Tools.For.UmbracoV8.Models;
    using AF.Examine.Index.Tools.For.UmbracoV8.ValueSetBuilders;
    using Examine;
    using System.Collections.Generic;
    using System.Linq;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    using Umbraco.Examine;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Populators
    {
        public class AFMembersIndexPopulator : IndexPopulator<IUmbracoMemberIndex>
        {
            private readonly AFMembersIndexValueSetBuilder _afMembersIndexValueSetBuilder;
            private readonly IMemberService _memberService;
    
            public AFMembersIndexPopulator(AFMembersIndexValueSetBuilder AFValueSetBuilder, IMemberService memberService)
            {
                _memberService = memberService;
                _afMembersIndexValueSetBuilder = AFValueSetBuilder;
    
                RegisterIndex("AFMembersIndex");
            }
    
            protected override void PopulateIndexes(IReadOnlyList<IIndex> indexes)
            {
                if (indexes.Count == 0) return;
    
                const int pageSize = 1000;
                var pageIndex = 0;
    
                IMember[] members;
    
                //no node types specified, do all members
                do
                {
                    members = _memberService.GetAll(pageIndex, pageSize, out _).ToArray();
    
                    if (members.Length > 0)
                    {
                        // ReSharper disable once PossibleMultipleEnumeration
                        foreach (var index in indexes)
                            index.IndexItems(_afMembersIndexValueSetBuilder.GetValueSets((IMember[])members));
                    }
    
                    pageIndex++;
                } while (members.Length == pageSize);
            }
        }
    }
    

    ValueSetBuilder

    using AF.Examine.Index.Tools.For.UmbracoV8.Models;
    using Examine;
    using System.Collections.Generic;
    using Umbraco.Core.Models;
    using Umbraco.Examine;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.ValueSetBuilders
    {
        public class AFMembersIndexValueSetBuilder : IValueSetBuilder<IMember>
        {
            public IEnumerable<ValueSet> GetValueSets(params IMember[] UmbracoMembers)
            {
                AFMembersModel AFMembers;
    
                foreach (var Member in UmbracoMembers)
                {
                    AFMembers = new AFMembersModel(Member);
    
                    Dictionary<string, object> indexValues = new Dictionary<string, object>
                    {
                        ["memberId"] = AFMembers.id,
                        ["memberNodeName"] = AFMembers.nodeName,
                        ["memberNodeTypeAlias"] = AFMembers.nodeTypeAlias,
                        ["memberLoginName"] = AFMembers.loginName,
                        ["memberEmail"] = AFMembers.email,
                        ["memberName"] = AFMembers.memberName,
                        ["memberSurname"] = AFMembers.memberSurname,
                        ["memberIntTel"] = AFMembers.memberIntTel,
                        ["memberFax"] = AFMembers.memberFax,
                        ["memberCel"] = AFMembers.memberCel
                    };
    
                    ValueSet valueSet = new ValueSet(AFMembers.memberId.ToString(), "afMember", indexValues);
    
                    yield return valueSet;
                }
            }
        }
    }
    

    Members Model

    using Umbraco.Core.Models;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Models
    {
        public class AFMembersModel
        {
            public string memberId { get; set; }
            public string memberNodeName { get; set; }
            public string memberNodeTypeAlias { get; set; }
            public string memberLoginName { get; set; }
            public string memberEmail { get; set; }
            public string memberName { get; set; }
            public string memberSurname { get; set; }
            public string memberIntTel { get; set; }
            public string memberFax { get; set; }
            public string memberCel { get; set; }
    
            public AFMembersModel(IMember AFMember)
            {
                memberId = AFMember.Id.ToString();
                memberNodeName = AFMember.Name;
                memberNodeTypeAlias = AFMember.ContentTypeAlias;
                memberLoginName = AFMember.Username;
                memberEmail = AFMember.Email;
                memberName = (AFMember.GetValue("memberName") != null) ? AFMember.GetValue("memberName").ToString() : string.Empty;
                memberSurname = (AFMember.GetValue("memberSurname") != null) ? AFMember.GetValue("memberSurname").ToString() : string.Empty;
                memberIntTel = (AFMember.GetValue("memberIntTel") != null) ? AFMember.GetValue("memberIntTel").ToString() : string.Empty;
                memberFax = (AFMember.GetValue("memberFax") != null) ? AFMember.GetValue("memberFax").ToString() : string.Empty;
                memberCel = (AFMember.GetValue("memberCel") != null) ? AFMember.GetValue("memberCel").ToString() : string.Empty;
            }
        }
    }
    
  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 04, 2021 @ 15:37
    Nik
    1

    Congrats on getting it working Adriano #H5YR

  • Adriano Fabri 469 posts 1633 karma points
    Jun 01, 2021 @ 08:56
    Adriano Fabri
    0

    Hi Nik,

    almost everything function properly but there is a problem after new member creation.

    When I try to create new AFMember, the index not rebuild after save action (I tried both in backoffice and programmatically)

    Where can I put a directive to force rebuild my custom index after new AFMember creation/update?

    Thanks

    Adriano

  • Adriano Fabri 469 posts 1633 karma points
    Jun 01, 2021 @ 11:17
    Adriano Fabri
    0

    SOLVED

    I had to modify my Custom Index Creator as follows.

    Now I have my custom index always updated.

    Adriano

    using Examine;
    using Lucene.Net.Analysis.Standard;
    using Lucene.Net.Util;
    using System.Collections.Generic;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Services;
    using Umbraco.Examine;
    using Umbraco.Web.Search;
    
    namespace AF.Examine.Index.Tools.For.UmbracoV8.Creators
    {
        public class AFMembersIndexCreator : UmbracoIndexesCreator
        {
            private readonly IProfilingLogger _profilingLogger;
            private readonly ILocalizationService _languageService;
            private readonly IPublicAccessService _publicAccessService;
            private readonly IMemberService _memberService;
            private readonly IUmbracoIndexConfig _iUmbracoIndexConfig;
    
            // Since Umbraco 8 has dependency injection out of the box, we can use it to inject
            // the different services that we need.
            public AFMembersIndexCreator(IProfilingLogger profilingLogger, 
                                            ILocalizationService languageService, 
                                            IPublicAccessService publicAccessService, 
                                            IMemberService memberService, 
                                            IUmbracoIndexConfig umbracoIndexConfig) : base(profilingLogger, languageService, publicAccessService, memberService, umbracoIndexConfig)
            {
                _profilingLogger = profilingLogger;
                _languageService = languageService;
                _publicAccessService = publicAccessService;
                _memberService = memberService;
                _iUmbracoIndexConfig = umbracoIndexConfig;
            }
    
            // Noticed that we return a collection of indexes? Technically you
            // can create multiple indexes in an indexCreator :) You can have a look at
            // UmbracoIndexesCreator.cs in the CMS core and see how the CMS does that.
            public override IEnumerable<IIndex> Create()
            {
                // create my AFMembersIndex definitions
                return new[] { CreateAFMembersIndex() };
            }
    
            private IIndex CreateAFMembersIndex()
            {
                var AFMembersIndex = new UmbracoMemberIndex(
                                                        "AFMembersIndex",
                                                        new FieldDefinitionCollection(
                                                            new FieldDefinition("memberId", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberNodeName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberLoginName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberEmail", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberName", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberSurname", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberIntTel", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberFax", FieldDefinitionTypes.FullText),
                                                            new FieldDefinition("memberCel", FieldDefinitionTypes.FullText)
                                                        ),
                                                        CreateFileSystemLuceneDirectory("AFMembersIndex"),
                                                        new StandardAnalyzer(Version.LUCENE_30),
                                                        ProfilingLogger,
                                                        UmbracoIndexConfig.GetMemberValueSetValidator());
    
                return AFMembersIndex;
            }
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft