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
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 folderI 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
folderI 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
andBundleConfig.RegisterBundles
method calls fromGlobal.asax.cs
Deleted
ApplicationConfig.cs
andBundleConfig.cs
from theApp_Start
folderRemoved the
@Styles
,@Scripts
and@RenderSection
directives fromViews/Shared/_Layout.cshtml
Deleted the
Content
andScripts
foldersAdded an
.editorconfig
fileWent through every file remaining in the solution (apart from files in the
Kentico
folder) andRemoved any unnecessary using declarations and comments
Made sure the code was formatted based on my editorconfig rules
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:
It achieves my stated goal
It provides my app with modern configuration capabilities such as easy integration with Azure Key Vault and Azure App Configuration
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 thetargetFramework
attribute of thesystem.web/httpRuntime
element to4.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
fileFind 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 inweb.config)
Add the following attribute to both the
connectionStrings
andappSettings
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 settingCMSConnectionString
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.