Chris Meagher

Creating a skeleton Kentico Xperience application

The shipping skeleton pattern normally starts with an empty (or "Hello world") solution that typically does not deliver any useful functionality. I know that my aim is to develop and deliver an application based on the Kentico Xperience (formerly Kentico CMS/EMS) platform however so I think it makes sense to set up a really basic Xperience app to use in my shipping skeleton, which will just be a clean Xperience install with a few modifications to tidy up and configure the default installation.

At the end of this article I will have a "skeleton" Xperience web app that is committed to a Git repo and ready to be released by a continuous delivery pipeline.

Xperience installation

I am going to assume that if you are reading this article that you are familiar with Xperience and have the Kentico v12 installer (the installer hasn't yet been rebranded) installed and patched to the latest hotfix.

Ok first up is a basic Kentico Xperience MVC install:

  • I create a new Git repo for my project - I'm going to call this project "Kentico Zero" - and add a remote on GitHub

  • I like to install Kentico to a src folder in the root of my repo so I create the folder

  • I then start the Kentico v12 installer and choose "Custom installation"

  • My development model is MVC

  • I don't register to IIS (I will use IIS Express for local dev), and I create a new site called "KenticoZero" in my src folder

  • I install with database to a local SQL Server instance using Window auth and create a new database called "kentico-zero"

  • I do not add any Components or enroll in the Kentico improvement program

  • I finish the installation wizard and wait for the installation to complete

After the installer completes I need to do a couple more things before I can browse the Admin (CMS) or Presentation (MVC) apps and verify the installation:

  • Configure IIS Express

  • Configure the site

Configure IIS Express

The Kentico v12 installer creates two solutions - one for the Admin app (always named "WebApp.sln"); and one for the Presentation app (in my case named "KenticoZero.sln"). I need to configure IIS Express for both apps so I follow the same steps in both solutions:

  • Select the web app project and view the Properties window (F4)

  • Under "Development server" change "SSL Enabled" to true

  • Copy the "SSL URL" value that is generated

  • Edit the web app project Properties (Alt + Enter)

  • On the "Web" tab, change the "Start Action" to "Start URL"

  • Paste the "SSL URL" you just copied from the Properties window into the "Start URL" and save

  • I then build the solution so it's ready for use

Configure the site

I now need to do some basic configuration of the site via the Admin app before the Presentation app will function:

  • Browse to the Admin app using IIS Express

  • Sign in using the default administator account credentials

  • Go to "Licenses" and add my license (I'm using a Free edition license for this project)

  • Go to "Sites" and edit my "KenticoZero" site

  • Change the "Site domain name" to match the host and port of the "SSL URL" of the Admin app e.g. localhost:44364

  • Change the "Presentation URL" to match the "SSL URL" of the Presentation app e.g. https://localhost:44374/

I can now browse to the Presentation app using IIS Express and verify that I see the default "Welcome" message.

Tidying up the default installation

A default Xperience installation is pretty weighty - around 10,000 files at just under 500MB on disk (not including NuGet packages). As with all projects the first thing I will do is get a sensible .gitignore file in place so I don't commit and push any unneccessary files (generated files, log files etc) to my repo.

I also want to do a bit of tidying up of the solutions created by the Kentico installer. This step isn't strictly necessary, but I want to make the solutions as tidy as possible and it doesn't take a lot of effort so I think it's worth it.

Tidying the Admin solution

The Admin solution includes a lot of code and files that support the various site templates offered by Kentico - these are superfluous to my project as they will never be used. I know that ignoring and removing them can cause pain when applying hotfixes though because the hotfix process adds the references back into the CMSApp.csproj file and can end up breaking builds as you have to go back through and remove the references again every time you apply a hotfix.

I want to ignore and remove the superfluous files (and I have done in the past), but I end up keeping them for this project because I don't think it's worth introducing the additional effort required when applying hotfixes.

That was a long way of saying I didn't do anything to the Admin solution, but I feel better for sharing!

Tidying the Presentation solution

The Presentation solution is more easily tidied up - it still contains code and files that are updated via Kentico NuGet packages when applying a hotfix (the Kentico folder), but the majority of the application is mine to do what I like with!

This is what I ended up doing:

  • Removed the ApplicationConfig.RegisterFeatures and BundleConfig.RegisterBundles method calls from Global.asax.cs

  • Deleted ApplicationConfig.cs and BundleConfig.cs from the App_Start folder

  • Removed the @Styles, @Scripts and @RenderSection directives from Views/Shared/_Layout.cshtml

  • Deleted the Content and Scripts folders

  • Added an .editorconfig file

  • Went through every file remaining in the solution (apart from files in the Kentico folder) and

    • Removed any unnecessary using declarations and comments

    • Made sure the code was formatted based on my editorconfig rules

I may very well end up having to put some of these things back as I start to build out the app, but the point is that I don't need them right now for a shipping skeleton.

Configuration builders

Before I commit and push my skeleton app to my repo I wanted to make sure I wasn't committing any sensitive configuration values to source control. There's a few ways to achieve this, but I like to use Configuration builders because:

Before I can use Configuration builders I need to change the target framework of the Admin and Presentation apps.

Change target framework

Configuration builders require that you target .NET 4.7.1 as a minimum. The apps produced by the Kentico v12 installer target .NET 4.6.1 (there is no option to change the target .NET Framework in the installer, though I wish there was). I need to change the target framework of each of the apps myself, which is pretty straight-forward, if a bit laborious.

I also want to take this opportunity to move the location of the NuGet packages folder, which is currently located under src, but I want it at the root of my repo. To achieve this I add a nuget.config file that sets the "repositoryPath" to ./packages.

I then follow these steps on the Admin and Presentation apps to change the target framework and relocate the NuGet packages:

  • Follow the steps documented by Kentico to change the target framework (including the recommended steps with the Package Manager Console)

  • Edit the csproj file and remove any elements that reference ..\packages\, but leave elements that reference ..\..\packages\

  • Edit the web.config file and change the targetFramework attribute of the system.web/httpRuntime element to 4.7.2

  • Rebuild the solution

  • Browse to the app using IIS Express to make sure that it still functions

Finally, I delete the src/packages folder as it has now been relocated.

Add Configuration builders

I want to use User Secrets for managing configuration secrets in my dev environment and I want a user secrets file per app so I do the following on both the Admin and Presentation apps:

  • Add a NuGet reference to Microsoft.Configuration.ConfigurationBuilders.UserSecrets

  • Edit the web.config file

  • Find the "Secrets" config builder element and add the attribute: mode="Greedy" (this ensures that all key/value pairs from the secrets file are made available even if they are not present in web.config)

  • Add the following attribute to both the connectionStrings and appSettings elements: configBuilders="Secrets" (this makes the key/value pairs from the secrets config builder available via those configuration elements)

  • Right-click the app project in the Solution Explorer and click on "Manage User Secrets" (this creates and opens the secrets file for editing)

I can now update the configuration of the individual apps.

Admin app configuration

There are only a couple of things that I consider to be a secret in the default configuration so I move those out of web.config and into my secrets file:

  • CMSHashStringSalt app setting

  • CMSConnectionString connection string

The Admin app secrets file now looks like the below, and the equivalent elements are removed from web.config:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <secrets ver="1.0">
        <!-- AppSettings -->
        <secret name="CMSHashStringSalt" value="ValueFromWebConfig" />
        <!-- ConnectionStrings -->
        <secret name="CMSConnectionString" value="ValueFromWebConfig" />
    </secrets>
</root>

I also remove the CMSTrialKey app setting because I don't need it, and browse to the app using IIS Express to make sure that it still functions.

Presentation app configuration

I move the exact same settings out of web.config and into my secrets file as I did for the Admin app, and make sure I remove them from web.config.

I also change the CMSCIRepositoryPath app setting value to a relative path (I'm not going to be using CI as it's not available on the Free license, but an absolute path makes no sense for team development if I were!), and browse to the app using IIS Express to make sure that it still functions.

Conclusion

And that's it - I now have a skeleton Kentico Xperience site that is clean, working, and doesn't leak configuration secrets! I commit everything that I have done so far and push to my remote on GitHub.

It would be nice to streamline some of the above steps to make this process quicker on future new projects, however it took way longer to type out than it did to do it so I don't think I will (yet) put effort into automating some of these steps - I may come back and review that at the end of this series however.

It would also be nice if Xperience:

  • Offerred a choice of which .NET Framework version to target during installation - the most time consuming part of this whole process is waiting for the NuGet packages to reinstall after you change the target framework!

  • Didn't install all the starter site files by default and didn't try to put them back in when applying hotfixes if you've removed them - the default installation is large enough without the extra weight of files I'm never going to use

  • Made the platform truly modular as there are a lot of modules included in the default install that I wouldn't include if i was given the choice - especially for a "skeleton" app like this

    • I know you can opt out of certain modules, but this again causes issues with hotfixes so isn't worth the effort

Next up I will be looking at hosting infrastructure for my Xperience site and automating the creation and management of that infrastructure.