Copied to clipboard

Flag this post as spam?

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


  • Daniel Rogers 140 posts 718 karma points
    Sep 20, 2024 @ 12:09
    Daniel Rogers
    0

    Umbraco14 Get data type folder by name

    Trying to create a data type folder programmatically in a migration.

    Then will create the data types in that folder.

    Im trying to create folders in the data types programatically Old v13 method was

    Guid contKey = new Guid();
    var container = _contentTypeService.CreateContainer(containerId, contKey, name);
    if (!container.Success)
    {
        // Declare the array of IDs to lookup
        int[] ids = new int[0];
        return _contentTypeService.GetContainers(ids).FirstOrDefault(x => x.Name == name && x.ParentId == containerId).Id;
    }
    else { return container.Result.Entity.Id; }
    

    However .CreateContainer is obsolete now and are using IDataTypeContainerService is recommended but has some crucial functions missing.

    Mainly get container by name.

    If I create the folder structure from scratch this is fine but when you come to update it later need to be able to find it from a know value.

    How do you search the datatype container to find a existing folder.

    this code creates it if not existent. or returns "DuplicateName" if already their.

    _dataTypeContainerService.CreateAsync(Guid.NewGuid(), name, parentKey, user.Key);

    What is the best way to get the Guid of the folder via its name.

    Any thoughts.

  • Daniel Rogers 140 posts 718 karma points
    Sep 22, 2024 @ 13:37
    Daniel Rogers
    0

    I think I have figured it out. But It has highlighted some shortfalls and errors in the IDataTypeCOntainerService.

    1. There is no way of accessing the containers by either name or Id only Guid. This is rather limiting if you don,t know the Guid.

    To make this work I have to routines one to find it the container exists the second to create it if it doesn't.

    Find the container requires accessing the database directly and search for by name and parent key.

        private const string __rootDataContainer = "IBD Data Types";
    private const string __options = "Options";
    
    private Guid? GetExistingDataType (IUmbracoDatabase Database, Guid? parentKey, string name)
        {
            string? p = parentKey == null ? "-1" : _dataTypeContainerService.GetAsync((Guid)parentKey).Result.Id.ToString();
            Sql sql = Database.SqlContext.Sql().Select("[uniqueId]").From("[umbracoNode]").Where(string.Format("[text] = '{0}' and [nodeObjectType] = '521231E3-8B37-469C-9F9D-51AFC91FEB7B' and parentId = {1}", name, p));
            var result = Database.QueryAsync<Guid>(sql).FirstAsync();
            return result.IsCompletedSuccessfully ? result.Result : null;
        }
    

    then if this returns a null create the container

        public Guid? GetOrCreateDataTypeContainerId(Guid? parentKey, string name)
        {
            int[] ugIds = new int[0];
            var userGroup = _userGroupService.GetAsync(ugIds).Result.FirstOrDefault(x => x.Name == "Administrators");
            IUser? user = _userService.GetAllInGroup(userGroup.Id).First();
    
            var container = _dataTypeContainerService.CreateAsync(Guid.NewGuid(), name, parentKey, user.Key);
            return container.Result.Success ? (Guid)container.Result.Result.Key : null;
        }
    

    So creating my containers I call them like this

        Guid? rootDataContainerKey = GetExistingDataType(Context.Database, null, __rootDataContainer) ?? GetOrCreateDataTypeContainerId(null, __rootDataContainer);
        Guid? optionsId = GetExistingDataType(Context.Database, rootDataContainerKey, __options) ?? GetOrCreateDataTypeContainerId(rootDataContainerKey, __options);
    

    This works to a point and this is where the second issue arises

    1. dataTypeContainerService.CreateAsync has an issue in that if a container with same name exists (at this stage have only proved if _options is in the root) then it dosent create _options under _rootDataContainer.

    Expected result would be

    IBD Data Types
         Options
    Options -- pre existing folder
    

    Instead result is

    IBD Data Types
    Options -- pre existing folder
    

    and _dataTypeContainerService.CreateAsync returns a "DuplicateName"

    If Options doesn't exist at all then it creates the correct structure

Please Sign in or register to post replies

Write your reply to:

Draft