Sitecore CM Initialization Error with Docker

Having set up a local Sitecore Docker instance using 10.1 I was facing errors in that all containers would appear to be running in a healthy manner, yet visiting CM was giving a 404. The first port of call was the CM Docker logs which showed that Sitecore was constantly rebooting itself. The error in the logs wasn’t too descriptive:

1764 14:17:09 WARN  Sitecore shutting down

1764 14:17:09 WARN  Shutdown message: Initialization Error

HostingEnvironment initiated shutdown

#Software: Microsoft Internet Information Services 10.0

#Version: 1.0

#Date: 2022-05-23 13:17:00

To try and find out more about this error I viewed the Event Viewer logs which had a little more to say:

exec's CreateProcess() failed [module=libcontainerd namespace=moby container=134faed94d3bc941f571014697d5b56a84eb8bd21498d9c775c0657d35b13918 exec=9ab6c42b86349f8db923386fe153838c6ac491c3712d81382d074148ce10ddb0 error=container 134faed94d3bc941f571014697d5b56a84eb8bd21498d9c775c0657d35b13918 encountered an error during hcsshim::System::CreateProcess: failure in a Windows system call: The user name or password is incorrect. (0x52e)
[Event Detail:  Provider: 00000000-0000-0000-0000-000000000000]
[Event Detail:  Provider: 00000000-0000-0000-0000-000000000000]
[Event Detail: onecore\vm\compute\management\orchestration\vmhostedcontainer\processmanagement.cpp(173)\vmcomputeagent.exe!00007FF600D69F4B: (caller: 00007FF600D1E13A) Exception(3) tid(4c8) 8007052E The user name or password is incorrect.
    CallContext:[\Bridge_ProcessMessage\VmHostedContainer_ExecuteProcess] 
 Provider: 00000000-0000-0000-0000-000000000000]]

A bit of Googling suggested that the local user may not have been added to the docker-users group in Windows Local Users and Groups:

Unfortunately this wasn’t the case for me but for good measure I added the Administrators group to this user group. As Hyper-V is required I also looked at the Hyper-V Administrators group to find that it was empty:

localusersdocker.png

Going for the belt and braces approach I also added both my local user account and the Administrators group to the Hyper-V Administrators group. This appears to have resolved the issue, and my CM Docker container successfully loaded.

Advertisement

Sitecore Handler AspNetCoreModuleV2 issues following 10.2 install

When upgrading Helix Base to Sitecore 10.2 I started to encounter an error upon attempting a CLI command ‘dotnet sitecore login’, after installing 10.2 locally:

After some further investigation I noticed that the identity provider site https://helixbase.identityserver.dev.local/ was throwing a runtime error:

Sitecore Handler “AspNetCore” has a bad module “AspNetCoreModuleV2” in its module list

A visit to the Modules section of the identity server IIS site showed that the AspNetCoreModuleV2 was missing:

This module is part of the .ASP.NET Core Hosting Bundle, and can be found in the Microsoft Documentation.

After installing the .NET Core Hosting Bundle locally the issue was resolved, and the missing module can be seen in the Modules list:

The Little Book of Sitecore® Tips volume 3 now available

Following volume 1 & volume 2 I’m pleased to announce the launch of volume 3 of The Little Book of Sitecore® Tips.

Like many other things in the current crisis, this release faced some delays but is finally available for order. Just like the preceding books, these tips were created from my workings with the Sitecore platform, producing another volume of this little series.

To repeat the common theme – The main purpose of The Little Book of Sitecore Tips series is a light-hearted look at some useful Sitecore tips. Hopefully you find this an enjoyable read, and learn something new along the way.

Your can order the next volume from the likes of Amazon and Barnes & Noble – The book is also available as an eBook on various stores.

Thanks is due to the team at Ethisys, and to technical reviewers Akshay Sura and Kamruz Jaman – and the usual thanks to Tamas Varga who was as helpful as ever. Thanks to Adam Seabridge, and Alex Washtell who supplied some nice reviews:

“Whether you’re a Sitecore Newbie or battle-hardened veteran there is a tip for everyone in this great little book, and unlike most techie books you’ll probably enjoy reading it too!”

Neil packs an incredible amount of useful tips into a tiny space, whilst also making room to present them in a fun and digestible way. There’s so much to get out of this book!”

SPE: Auto generating C# for Sitecore with a right-click

Having undertaken a large migration from WebForms to MVC which included migrating from an ORM to Glass, I decided to create a ‘C# Source Generator’ SPE Module which allows you to right-click Sitecore items and auto generate C# code. This can be used on all projects to save time writing source and can automate any general mundane tasks. The current options are shown below:

These can be operated with a right-click on any Sitecore item. For example, a right-click on the Hero template in Helix Base allows me to generate a Glass fluent mappings class :

The C# output is as follows:

Below is a breakdown of each script:

  • Generate Constants for ALL Templates

This outputs a large amount of source containing constants for every single template Guid in the Templates directory recursively. The property names are created from the item path in the Sitecore content tree to avoid any duplicated constant names.

Availability: This option appears on a right-click of any item in the content tree.

Example Output:

  • Generate Constants for Child Items

As above but generates constants for children and uses a simplified item name for the property, the item name will be appended with ‘Content Type’ or ‘Page Type’ if it resides at one of these paths.

Availability: This option appears on a right-click of any item in the content tree.

  • Generate Constants for Current Item

As above but generates constants for current item.

Availability: This option appears on a right-click of any item in the content tree.

  • Generate Controller for Child Items

This will generate a controller source for all child items. The source follows a mediator pattern as found in Helix Base and the controller name is based upon the item name.

Availability: This option appears on a right-click of any item that is a Sublayout Folder or a Rendering folder

Example Output:

  • Generate Controller for Current Item

As above but generates controllers for the current item.

Availability: This option appears on a right-click of any item that is a Sublayout or Controller rendering

  • Generate Mediator for Child Items

This will generate mediator application layer source for all child items. The source follows the mediator pattern as found in Helix Base and the class name is based upon the item name. An interface will also be generated.

Availability: This option appears on a right-click of any item that is a Sublayout Folder or a Rendering folder

Example Output:

  • Generate Mediator for Current Item

As above but generates mediator source for the current item.

Availability: This option appears on a right-click of any item that is a Sublayout or Controller rendering

  • Generate Service for Child Items

This will generate service application layer source for all child items. The source follows the service pattern as found in Helix Base and the class name is based upon the item name. An interface will also be generated.

Availability: This option appears on a right-click of any item that is a Sublayout Folder or a Rendering folder

Example Output:

  • Generate Service for Current Item

As above but generates service source for the current item.

Availability: This option appears on a right-click of any item that is a Sublayout or Controller rendering

  • Generate ViewModel Factory for Child Items

This will generate viewmodel factory application layer source for all child items. The source follows the factory pattern as found in Helix Base and the class name is based upon the item name. An interface will also be generated.

Availability: This option appears on a right-click of any item that is a Sublayout Folder or a Rendering folder

Example Output:

  • Generate ViewModel Factory for Current Item

As above but generates factory source for the current item.

Availability: This option appears on a right-click of any item that is a Sublayout or Controller rendering

  • Generate Fluent Mappings for Child Templates

This will create source that contains classes for Glass fluent mappings. The class names and field names are generated from the item name (which is cleaned), and the item name will be appended with ‘Content Type’ or ‘Page Type’ if it resides at one of these paths. This script will auto generate a ‘config.Field’ mapping for any fields that contain a space in the name. These field mappings are generated for Helix interface type templates only.

Availability: This option appears when right clicking any Template Folder item, usually found in the Templates node.

Example Output:

  • Generate Fluent Mappings for Current Template

As above but generates mappings for current template.

Availability: This option appears on a right-click of any item with a ‘Template’ template type.

  • Generate Interfaces for Child Templates

This will output a C# interface for each child template, with properties added to the template. Inheritance is not added to source (see Generate Interface from Standard Values for this). The class name will be appended with ‘Content Type’ or ‘Page Type’ if it resides at one of these paths. The C# properties are generated for Helix interface type templates only. The properties are mapped into C# types using the following dictionary which is fairly basic at the moment but can be extended in future:

$fieldMappings = @{}
$fieldMappings.Add('Integer','int')
$fieldMappings.Add('Checkbox','bool')
$fieldMappings.Add('Single-Line Text','string')
$fieldMappings.Add('Number','int')
$fieldMappings.Add('General Link','Link')
$fieldMappings.Add('Multi-Line Text','string')
$fieldMappings.Add('Rich Text','string')
$fieldMappings.Add('Date','DateTime')

A future update could map a property as the correct interface type for Treelist, Droplist and so on. Property names are created from the item name.

Availability: This option appears when right clicking any Template Folder item, usually found in the Templates node.

Example Output:

  • Generate Interface for Current Template

As above but generates source for the current template.

Availability: This option appears on a right-click of any item with a ‘Template’ template type.

  • Generate Interface from Standard Values

This will output a C# interface for a template that uses standard values, doing so allows an interface to be created that uses inheritance. The class name will be appended with ‘Content Type’ or ‘Page Type’ if it resides at one of these paths. Properties are not generated for the interface as in a Helix solution it will usually inherit an interface template.

Availability: This option appears on a right-click of any item with a ‘Template’ template type.

Example Output:

  • Create Controller Rendering from Sublayout

This script doesn’t generate C#, it is helpful for a WebForms to MVC conversion and will generate a Controller Rendering, copying over the values from the Sublayout. A prompt will appear for the user to select where the new rendering should appear in the content tree.

Availability: This option appears on a right-click of any item with a ‘Sublayout’ template type.

The scripts can be found in Helix Base

Applying Helix code analysis to GitHub repos – Step by step

Whilst working alongside Rad Kozlowski, he recently created a GitHub action that can be applied to any Helix Github repo. This runs an automated analysis on the source to check for Helix compliance. HelixCheck was launched and I have set this up on a Helix Base feature branch with a tutorial below:

Step 1: In your GitHub repository select the ‘Actions’ tab. Here you will see a list of actions that are running on this repository:
Step 2: With your current actions visible, select ‘New workflow’, this will open the following screen where we will select ‘set up a workflow yourself’:
Step 3: This will open the new workflow screen:
Step 4: Delete the contents of this screen and replace with the HelixCheck action, I’ve added descriptive comments:
Below is the code to copy and paste, you can also find the file on Helix Base:
name: Helix Check on 9.2 branch

# Controls when the action will run. HelixCheck workflow will run on push
# events but only for the feature 9.2 branch 
on:
  push:
    branches: [ feature/9.2.0 ]

# Set up the HelixCheck job
jobs:
  check_job:
    name: Helix check
    runs-on: ubuntu-latest

# Check out the repo
    steps:
      - name: Checkout
        uses: actions/checkout@v2

# Configure the Helix Check step
      - name: Helix Check
        uses: ethisysltd/helix-check@v1.0
        id: check
        with:
          solution-file: 'Helixbase.sln' # Set the name of your solution file here
          project-name: 'Helixbase' # Add the project name here. Helix Base naming is Helixbase.Feature.Hero for example so the project name is 'Helixbase'
          website-folder: 'website' # Older versions of Helix will use 'code' here, newer is 'website'
      
      # Output the HelixCheck results
      - name: Get the check result
        run: echo "Check result - ${{ steps.check.outputs.result }}"
      
      - name: Get the output time
        run: echo "The time was - ${{ steps.check.outputs.time }}"

Once you save the action you can then see an output of the results under Actions:

Any issues within the project relating to Helix compliance will now be listed here. This action can be applied to any event or any branch which means automated code analysis on any Helix GitHub repo, excellent work Rad!

Working with the with New csproj format in Sitecore: Issue#1 RazorGenerator.MsBuild

Many of us have been using precompiled views for a while in Sitecore and the new csproj format for .NET Core is something we’d like to utilise, but the new csproj format does present us with some challenges. One such issue presents itself when using RazorGenerator.MsBuild, which can cause the following issue when trying to compile the solution:


2>------ Build started: Project: Helixbase.Feature.Hero, Configuration: Debug Any CPU ------
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : Could not precompile the file '\Views\Layouts\Helixbase\Default.cshtml'. Ensure that a generator declaration exists in the cshtml file. 
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : A generator declaration is the first line of your cshtml file and looks like this: 
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : @* Generator: MvcHelper *@
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : Valid host names: MvcHelper, MvcView, Template, WebPagesHelper, WebPage, RazorGenerator.Core.IHostProvider

As the error states, one way around this is to add the generator declaration in each view @* Generator: MvcHelper *@ although in our Sitecore Helix solution it’s not practical to add this to every view.

There seems to be an issue in RazorGenerator.MsBuild in that it looks for System.Web.Mvc in the csproj and can’t find it. One workaround for this is to add the following to every csproj:

<!--System.Web.Mvc this line only exists so that razorgenerator picks this up as an mvc project -->

Adding this enables us to use precompiled views per project rather than adding them to every view in our Helix modules. You can see this in action on Helix Base until a more permanent fix is made to RazorGenerator.MsBuild

Introducing ‘Host Base’ – now available on GitHub

For anyone wishing to get started with a basic Sitecore Host app you can find documentation online. However, sometimes it’s easier to see a working example, therefore I have created Host Base as a starting point for anybody wishing to create a Host application.

Ultimately, the same principle will apply as Helix Base but presently Host Base is a very basic example that runs as a plugin within the Identity Server application. We’re presently limited to creating plugins for current Sitecore Host applications (such as Identity) – With this in mind, hopefully it’s a helpful starting point.

The application currently very simply writes information to the logs, and reads values from configuration. Stay tuned for updates as it grows in functionality.

I hope this is useful for anybody wishing to get started with this exciting form of Sitecore development.

Introducing ‘Helix Base Modules’ – now available on GitHub

Since its conception, Helix Base has been adopted as a starting point for Sitecore development (using Helix conventions) by a large number of individuals and organisations alike.

It was created with efficiency in mind and therefore was setup in a manner that ensures it remains as ‘lightweight’ as possible. This results in features being restricted to a few basic examples. Due to the amount of requests to add functionality to the solution that had to be rejected, I have now created Helix Base Modules which is an area for any willing contributors to upload their Helix Base module. This repo enables additional functionality to the framework whilst avoiding bloating the solution.

In an attempt to streamline the solution, I have refactored the ‘fun’ module from Helix Base and used this as a starting point for the new repo.

Please feel free to submit any useful Helix Base modules that you have created, and share them with the rest of the development community.

Glass.Mapper performance – Sitecore ORM benchmark test

I recently gave a talk at the Manchester Sitecore User Group and part of this involved presenting information regarding the performance of Glass.Mapper. To ensure that reliable information exists in the public domain regarding the speed of some popular Sitecore ORM’s a GitHub repository now exists to perform a benchmark test and I thought I’d expand on the talk and write up some results.

I executed the tests from the repository on Sitecore 9.0.1 with a machine spec of Intel Core i7 7th Gen @ 2.40GHz with 16GB RAM, and the following are covered in the benchmark test:

Native Sitecore API
Glass.Mapper v5.1.0
Fortis v4.2.2
Synthesis v9.0.1

Each test was executed three times and each test itself runs the code 1000 times, so if you’d expect faster speeds – this is why. The results are listed below with an average taken of the three test executions. There is also an explanation that focuses on Glass performance as this is a topic I’d most like to address in this blog post.

1. ‘New’ test:

This is a basic test for a new item, the results are as follows…

Sitecore: 0, 0, 0 = 0ms
Glass: 8, 9, 8 = 8.33ms
Fortis: 1, 1, 1 = 3ms
Synthesis: 0, 0, 0  = 0ms

Glass creates proxy items which maps our data to objects that are CMS agnostic, and with the mapping running through a config pipeline it’s probably expected that the additional features result in a slower speed. Other object mapping frameworks wrap the Sitecore API calls, so we see a similar result to the native API.

2. ‘RenderFields’ test:

This is as the test above plus some field mappings…

Sitecore: 497, 495, 505 = 499ms
Glass: 300, 256, 306 = 287.33ms
Fortis: 526, 470, 480 = 492ms
Synthesis: 492, 512, 474492.66ms

It’s interesting to note that the native API on this occasion is slower than Glass. This is because Glass does not use the Render Field pipeline for fields other than Rich Text. Rendering fields is a very common action as a Sitecore developer, so the performance gain here is one of the more important ones in the test. Obviously, the templates used here are basic, for templates with more fields I’d expect Glass to offer an even bigger performance enhancement.

3. ‘Children’ test:

This test simply maps children of an item but doesn’t contain any field mappings for the child items…

Sitecore: 81, 42, 59 = 60.66ms
Glass: 119, 111, 123 = 117.66ms
Fortis: 80, 70, 72 = 74ms
Synthesis: 49, 42, 47 = 46ms

Again, Glass offers additional features meaning in this instance each child runs through the relevant configuration pipelines where Glass checks the likes of template enforcement etc. A more complex type match offers more features but a slower map speed, once again we’re in the ‘Feature vs Speed’ situation. The other frameworks only contain basic type matching which enables a faster result.

4. ‘ChildrenWithFields’ test:

This test is the same as the previous one, but on this occasion, we map children of an item including field mappings…

Sitecore: 5511, 5561, 5580 = 5550.66ms
Glass: 893, 661, 651 = 735ms
Fortis: 1122, 973, 968 = 1021ms
Synthesis: 1054, 959, 974 = 995.66ms

A practical example of this would be a Menu item for example and here we see an example of where mapping frameworks excel when compared to the native API. The reasons for this again relates to the Render Field pipeline. When it comes to rendering fields, once again it’s Glass that returns the fastest result.

Combined total for all tests:

Sitecore: 0 + 499 + 60.66 + 5550.66 = 6060.32ms
Glass: 8.33 + 287.33 + 117.66 + 735 = 1148.32ms
Fortis: 3 + 492 + 74 + 1021 = 1590ms
Synthesis: 0 + 492.66 + 46 + 995.66 = 1534.32ms

Summary

The test doesn’t factor in how much time it takes to configure the ORM or work with it (or without it) on a daily basis. It also doesn’t necessarily account for the trade-off between the amount of features the ORM supplies vs the time taken to render a page. Other factors to consider are the likes of any time savings afforded to us when using an ORM and writing unit tests for example, or assistance when writing SOLID class design and maintainable/reusable code. As ever, nothing boils down to speed alone, we must weigh up the overall efficiency of the framework which means including all contributing factors, so there’s scope for another post here, potentially a part 2 coming in future.

While Glass is slower than the Sitecore API for specific calls, in the combined totals we can see that for general use there is a significant performance gain. It would seem impossible that an ORM could offer a performance gain over a native API, but we can see here this isn’t the case.

Why not learn more about Glass and study the training course, something I’d highly recommend.

Sitecore placeholders as a Droplist

When it comes to selecting a placeholder in Sitecore we are required to enter text into a Single-Line Text field:

placeholder select

Obviously this introduces scope for a typo and potentially isn’t an ideal user experience. So I thought we’d look at changing this to a Droplist. The good news is the first step is a very straightforward task and we only need to update the Standard Rendering Parameters template found at /sitecore/templates/System/Layout/Rendering Parameters/Standard Rendering Parameters

The Placeholder field can be updated to a Droplist with a source query that filters anything that’s not a ‘Placeholder’ template (/sitecore/templates/System/Layout/Placeholder). We can use a query such as:

query:/sitecore/layout/Placeholder Settings//*[@@templateid='{5C547D4E-7111-4995-95B0-6B561751BF2E}’]

Our Standard Rendering Parameters template now appears as follows:

sitecore rendering parameters

And we can now select our placeholders from a Droplist:

sitecore_rendering_params_dropdown

Bear in mind that we have directly updated a Sitecore template, so any platform update will replace this change. We could serialize the Standard Rendering Parameters template but adding a vanilla template to source control is never a good idea. Food for thought.

Sadly our work isn’t quite finished, while this works for the Control Properties Dialog we also need to think about the Select Rendering Dialog incase a user wants to add a rendering from the Device Editor:

sitecore rendering selection

This is a sheer UI control found at:

MYSITE/sitecore/shell/default.aspx?xmlcontrol=Sitecore.Shell.Applications.Dialogs.SelectRendering&hdl=0ECAC17C88F941F08B14CE06796BF366&ro=sitecore%3A%2F%2Fmaster%2F%7BEB2E4FFD-2761-4653-B052-26A64D385227%7D%3Flang%3Den%26ver%3D1&ic=SoftwareV2%2F16x16%2Fcomponent_blue.png&txt=Select%20the%20rendering%20that%20you%20want%20to%20use.%20Click%20Select%20to%20continue.&ti=Select%20a%20Rendering&bt=Select&rt=Id&sph=1&sop=1&str=1

So we need to find the XML Control that uses the class Sitecore.Shell.Applications.Dialogs.SelectRendering

This is found in \sitecore\shell\Applications\Dialogs\SelectRendering\SelectRendering.xml

Rather than manipulate the vanilla XML control, we can copy this file to the ‘override’ folder to ensure that our new control is used:

\sitecore\shell\override\Applications\Dialogs\SelectRendering\SelectRendering.xml

Edit the line:

<CodeBeside Type=”Sitecore.Shell.Applications.Dialogs.SelectRendering.SelectRenderingForm,Sitecore.Client”/>

And change this to the class in your project:

<CodeBeside Type=”Helixbase.Feature.Fun.SelectRenderingForm,Helixbase.Feature.Fun”/>

And for our code behind file we can copy the class ‘SelectRenderingForm’ which is found in Sitecore.Shell.Applications.Dialogs.SelectRendering of the Sitecore.Client.dll (or Sitecore.Shell.dll depending upon your version of Sitecore).

First we need to change the PlaceholderName property from an ‘Edit’ to a ‘Listbox’ type:

protected Listbox PlaceholderName { get; set; }

We then loop through our placeholder items and populate the Listbox (view below or on Gist)

 var database = Sitecore.Configuration.Factory.GetDatabase("master");

            var placeHolderItems= database.SelectItems("/sitecore/layout/Placeholder Settings//*[@@templateid='{5C547D4E-7111-4995-95B0-6B561751BF2E}']");

            foreach (var placeholder in placeHolderItems)
            {
                this.PlaceholderName.Controls.Add(new Sitecore.Web.UI.HtmlControls.ListItem
                {
                    Value = placeholder.Name,
                    Header = placeholder.Name
                });
            }

We can now see placeholders as a Droplist:

sitecore_placehodler_dropdown