How to convert Kentico CMS web site to a Web Application
Kentico CMS project ships as a web site by default, however, you may change this if you need it to be a web application for some reason. Let's see how ...
There are numerous discussions around the Internet on the differences between a web site project and a web application project, with no real answer to which one is better. That is why I wanted to present you my opinion, including step-by-step guide on how to convert the Kentico CMS application to the other model. This article is also sort of prerequisity of the next one I am planning, which should be about using ASP.NET MVC within Kentico CMS
project, needless to say, such project must be a web application.
Web application project (WAP)
Web application was historically actually the first model presented within ASP.NET. Sites of ASP.NET 1.1 were really the web applications that needed to be compiled into DLLs.
The main aspects how you can tell if the web is a web applications are following:
There is a .csproj (.vbproj) project file for the web site, which can be opened outside the actual solution.
The web site produces .dll file(s) into the bin folder of the project.
The page directives usually (but not necessarily, I will cover that later) contain CodeBehind="..." property, which means that the execution code of the page is compiled (taken from the DLL).
There are .Designer.cs (.vb) files for each of the components of the web site declaring the elements on the component programatically.
If you make a change to the code behind file, you need to compile it to get the changes on the live site.
If there is an App_Code folder, it is usually named Old_App_Code and comes from the project converted from web site project. Same with Old_App_Browsers. This is sort of precaution from .NET developers so the two compilation models do not collide. You will see why later.
So basically, it works like a regular class library, but with some declarative face coming from ASPX / ASCX files. One way or another, you need to compile it, which makes the solution not flexible enough for some situations where the dynamic compilation is required or you cannot use VS to compile your changes, which is typical for shared hostings or very dynamic systems like Kentico CMS. On the other hand, since the application code basically is a DLL, it can be used as one so you can refer to it from other projects, such as unit tests, which makes it more powerful if you really need this.
It is also the model first versions of Kentico were using. For some reason (and do not ask me why, since I don't really know), they removed this from ASP.NET 2.0 and replaced it with the web site model, which is much more flexible, but comes with other cons. Developers were angry, because they were not able to use the model they were used to anymore, so Microsoft had to reintroduce the original model as Web application project
. Firstly, it was just an addon, later, it became the regular part of the VS.
What we did as the result of this was we started to make Kentico CMS 2.0 on the web site project and did some features that are somehow depending on that one to fully work as designed. We stayed with web site project until now ... so far.
Web site project (WSP)
The web site project type is much more flexible from the code update perspective, but not as compatible with other aspects like referencing it from other DLLs or providing it as an apllication package, which will become interesting when the Azure support comes into the game.
Just as web application project, the web site project has it's own specifics:
There is always a .sln file and no specific project file for the project
There are no specific DLLs in the bin folder of the project, unless you precompile (or deploy) the web site. The web site can work even with the DLLs since it is compiled on-the-fly.
The page directives always contain the CodeFile="..." property, which tells the engine that this page is compiled dynamically (on-the-fly).
There are standard App_Code, App_Browsers folders
Since it is using the dynamic compilation, this type of project comes with one big advantage. Anything you change in the code is compiled upon the next request to that component, making the changes appear right away. So you may even update the files through FTP, and you get the result compiled and updated on the server without any need for deploying the whole project.
That is also the reason why we like it that much, simply because no matter how experienced the client is, his solution is always working without the need of recompilation.
Converting WSP to WAP
Conversion of a Kentico CMS web site project to a web application project isn't that different from conversion of a standard ASP.NET project. Afterall, that is exactly what a Kentico CMS web site is. A standard ASP.NET project. So what you need to do are pretty common steps of conversion. We will be converting just the code files, not the data, the database stays the same.
Start with new installation or your existing project
It doesn't matter if you use standard clean installation or an existing project you already have, the steps are the same. Just if you are using an existing project, definitely back it up to prevent any code or data loss. I will show this example on the clean installation, without any database installed yet. So I just ran setup, web installer, and installed a new project into folder c:\Inetpub\wwwroot\KenticoCMS55WAP.
Prepare the solution
Next thing to do is to prepare your solution for the new project. As I told you before, the WAP project has some project file, so we will need to create a new project for that purpose. Open the solution (WebProject.sln) and add a new project of type ASP.NET Web Application.
What it does is that it creates a new project of this type.
Before we continue, we need to do some cleanup. As you can see, there are the following files that are present in both projects:
Since our goal is to use both files from the existing project, delete those. We will use the ones from the Kentico project.
Move the content to the WAP project
Moving content of the project over through the VS is very slow (because it expands about every node of the file tree), so go to your file system and copy the files from one project to another. That will be much quicker. Then, if you click on the "Show all files" icon, you will see all the files below the project.
Select all the files you want to include in the project, right click and select "Include in project". I am not including the App_Data, bin and obj folder for a reason. They just do not contain anything that would need to be compiled, and it would take longer to include that. But you can sure do that, too.
That will make your files part of the project and also the compilation process. It will take some time now since there is a lot of files, so you can get your lunch, breakfast, or whatever. Just do not eat the dessert yet, you will have time for it later. When you return, all files should be included in your project.
Add the references
We will want to compile the project, so you need to add the references to all our DLLs. So just add the references to all DLLs within the bin folder of the project.
Convert the files to web application format
Since the files were only copied, they are still in the unwanted format which has web site project specifics. The most important thing that is not handled yet are the designer files. That is the main reason why we need to do the next step, which is converting the files to web application format.
It not only generates the designer files, but also relocates the App_Code to the correct folder. Once again, this takes quite a time, so have the dessert and coffee now if you want.
The code of the conversion in VS isn't perfect and for some reason it does the conversion in the batches that end randomly, so you may need to run the conversion several times (typically 2-3) to get all components converted. If you need to do it too many times and you get the errors about the cms prefix not being available, you probably didn't use the web.config from Kentico project.
You may also encounter an error with conversion related to our selectors. Again, for some reason VS isn't able to convert user controls that are based on server controls with ITemplate properties correctly if they contain the template content. This is the workaround you need to do to let them pass OK:
They are the following:
And you need to do this:
Locate such control
Comment out the templated code in the ASCX of cms:UniFlatSelector control in that contol (ASPX comment)
Convert the file to Web application format (through right-click menu)
Uncomment the commented code
That is the last thing you need to do during the conversion.
Compile the project
Now is the time when your project should be completely converted to a web application and you should be able to use it. So compile the project and run it. You should get a standard running project with database setup or your content.
Steps after conversion
Taking care about a web application project isn't always a simple thing. As you probably know, our export/import module also supports moving of the code files with the package, which basically violates the web application project rules at some point. That is the lack of flexibility of such project I mentioned.
So when you host a web application project, you need to include all new files that come from import package after the import to your project (through the show all files option), convert them to web application format (if they come from a web site project) and recompile the project. Same thing with any hotfix or upgrade procedure we currently provide, because we provide that for web site project.
On the other hand, you need to cleanup the files if you go the other way. Remove the designer files and change the CodeBehind to CodeFile manually.
With web site project, there is no need to do anything like that, since all files are always included, and compiled dynamically. So as you can see, having the web application project also comes with some price for it you must accept for being able to use it for other purposes.
Now you see why we offer the web site project by default, it is simply easier for you to handle and go with all the features working automatically.
WAP with web site features
Just a small note for those who like to play with the projects, seeking for better paths to go.
Since the Microsoft developers had to solve the compilation models not interfering with each other, they basically needed to enable both options, because in the end, the request still goes to the specific ASPX page and that page needs to decide whether to take compiled code from the DLL or dynamically from code behind. That is exactly what is determined by the CodeFile (dynamic) vs. CodeBehind (DLL). Funny thing is that simply by changing this, you may change your web application to use dynamic compilation for that specific element. To do that, you can just replace the CodeBehind with CodeFile, nothing more.
This can be done with entire project, except for the App_Code base, which must somehow be compiled. On the other hand, CodeFile files cannot be compiled that way, since there would be duplicity of classes from DLL and dynamic compilation, so the project must be separated into two (BTW, that is another great advantage of WAP, it may be split into several independent projects). One of them contains App_Code and is compiled within the solution, and the other one contains the rest of the project and is compiled dynamically as the pages display.
This way, you can achieve very flexible solution for your development. But it surely takes some playing around and experience to get it to working state. I think I will elaborate more on this later, when 6.0 comes out.
Believe me, we are using this with the development of the Kentico CMS 6.0 and it is incredible in the efficiency it provides.
Speaking of 6.0 ...
As I said before, even a web application has some positives that aren't provided by a web site project. You may build unit tests on it, you may even use MVC with it keeping the WebForms intact (as I will cover in my next post) or you may make an application package for deployment, which leads us to Azure. Azure is simply built on the rule that the projects are web applications shipped as packages with some specifics. Since we plan to support it in 6.0, there is also a plan how to provide web application based projects which includes:
Choice within the installation whether you want to install it as a web site, a web application or an Azure project.
Automatic support of WAP vs. WSP within the export/import module.
Small application for applying hotfixes and upgrades that will do the appropriate conversions of the upgrade package for you automatically.
In other ways, you will have the choice, which is always the best option. It will be up to you to make the right choice and the same choice may be in your mind right now. But we will probably leave the Web site project option the default one anyways.
How to make the choice
The choice alway comes with great responsibility, because based on it, your next development efficiency may be based and you do not want to spend resources on something your really don't need.
My advice is:
Do not convert to Web application unless you really need to or are told to do so by your supervisor or client (and unless you are able to make them think otherwise).
With Web application, always count with slower development, since you will need to recompile now and then (unless you use the combined option).
With Web application, always count with some additional actions required if some operation related to code base is done. The additional action will typically also be the compilation.
Code integrity is definitely not a reason why you should go with web application, since you can always compile the web site, too.
Same with the security. If you want to prevent a hacker to be able to change the code that would compile right away, you can use precompiled web site.
Also with the speed of the application. Unless you make a change to the code, the compiled code is cached within temporary files with the same effectivy as it goes from the DLL of WAP. Or, you may use the Precompilation.
The scenarios where you may want to use WAP are the following:
You need to write unit tests on it.
You are required to provide Web application package by the hosting company with no other options (which is not nice from them so you may think about how flexible they can be in the future).
You somehow need to split the development of the pages to several projects.
But be careful in balancing the pros and cons of this approach, the result should always justify the needs and additional time.
For most projects, it is probably better to just wait for version 6.0.
See you next time ...