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
srcfolder 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
srcfolderI 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
trueCopy 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:44364Change 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.RegisterFeaturesandBundleConfig.RegisterBundlesmethod calls fromGlobal.asax.csDeleted
ApplicationConfig.csandBundleConfig.csfrom theApp_StartfolderRemoved the
@Styles,@Scriptsand@RenderSectiondirectives fromViews/Shared/_Layout.cshtmlDeleted the
ContentandScriptsfoldersAdded an
.editorconfigfileWent through every file remaining in the solution (apart from files in the
Kenticofolder) 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
csprojfile and remove any elements that reference..\packages\, but leave elements that reference..\..\packages\Edit the
web.configfile and change thetargetFrameworkattribute of thesystem.web/httpRuntimeelement to4.7.2Rebuild 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.UserSecretsEdit the
web.configfileFind 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
connectionStringsandappSettingselements: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:
CMSHashStringSaltapp settingCMSConnectionStringconnection 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.
)