Razor Templates: Best Practices in Code Generation
Razor Templates are brilliant for Code Generation. However, there are a few significant issues. Razor Templates are fine-tuned to work extremely well with HTML, but can run into problems with languages like Javascript, TypeScript, C#, Java, JSON, etc. This article will outline these roadblocks and provide simple, effective fixes.
Problem 1: Starting and Ending Razor Code Block
The Problem
In Razor Templates the { and } symbols are used for code blocks. The problem is that other languages also use these same symbols (e.g. JavaScript, TypeScript, C#, Java). This can lead to issues where the Razor Template code becomes confused about where the code starts and finishes. This can cause lots of syntax errors.
Fixing this issue
The best way to fix this issue is to have the Razor Template contained within a code block then explicitly define where the text is (rather than having a text first template). To do this, choose the first line of your Razor template (after the Razor ‘using’s’) as the start of the code block. Then begin writing the Razor code with the symbols ‘@{‘.
Following this, each line which contains template text needs to then start with a @: This is how Razor defines the text in a code line.
Using this approach can make a huge difference. It defines specifically what part is Razor code and what is non-Razor Code.
Example
This example demonstrates the above fixs to the Razor Template. It shows the code before and after the fix.
Before The FIx

After The Fix

As can be seen above, the changes required are minimal. , yet the impact is significant.
Problem 2: Razor Template Syntax can be misinterpreted
The Problem
In the majority of software (i.e.Razor and C#, Javascript, etc.) the syntax symbols such as { are used in function calls. However, the problem is that Razor cannot accurately determine which is Razor code and which is non-Razor code! For example, in the following line, the ‘.Find’ is meant to be part of output text, but the syntax will be misinterpreted.
e.g. var invoice=@Model.Invoice.Find();
Fixing this issue
Instead of using an implicit expression @ always use explicit expressions @().
This use of explicit expressions will still accurately output code from the template. The change is the extra bracket. These extra brackets will help Razor understand specifically where the Razor code starts and ends.
Example
This example shows how to replace a @ call with @()
Before

After

Problem 3: Sharing code between Razor templates
The Problem
When writing complex Razor templates, extra functions can be added using this following call: @functions{}.
I think everyone agrees that copying and pasting code is a dangerous method of reusing code as this can lead to errors being introduced due to inconsistent modifications and bug fixes.
Fixing the issue
There are two methods for fixing this issue. The first method is by using a .Net DLL. This approach works with all razor templates but adds a large layer of complexity.
The second method is simpler and is built into the Razor Templates Engine used by SilverModel Code Generator, this allows the merging of different Razor Template into an existing one.
The following will look at method 1 and 2 in more details with pros and cons for each.
The following will describe each method
Method 1: Use a .Net DLL
As Razor can access .Net DLL’s, it is possible to move code into .Net DLL which you then reference in the template.
Example of referencing a .Net DLL in Razor Template.

These are a number of pros and cons when using a DLL.
Pros
- The full power of .Net and Visual Studio is available with these DLL’s when creating and debugging
- They can be Unit Tested
- Faster that template code as it is pre-compiled
Cons
- Can be harder to debug as the code is now separate from the template
- DLL’s need to be accessible by the template
- Less flexible to work with as all changes are made in the DLL, not the template
- Slower to make changes as you have to update the DLL and then test it in a template
It’s a judgement call as to whether to place the code in the template or a DLL. A DLL is more suited to code that is going to be reused by a lot of templates. More complex functions that require complex algorithms and extensive unit testing would be more suited to a DLL.
Method 2: Create a shared library of code in a Razor Template
This method works in SilverModel Code Generator, enabling the process of creating a shared library of code to be seamless and reliable. SilverModel has a preprocessor on the Razor templates and when it finds the statement @IncludeFile it will copy that file at that location into the template.
For example:

This above line will copy the file at ‘..\CQRS Shared Code\SharedFunctions. Razor’ and put the contents into the calling Razor Template, this allows the creation of a library of functions that can be shared and reused between templates.
Pros
- Efficient & fast to work with as code is part of the template
- Easy to modify an existing function for a template
- Creates a shared library of code for all templates
Cons
- Longer compile times for the razor template
- Can be harder to debug
- No Unit Testing
Summary
In summary, integrating Razor with other templates (and languages) can create problems. The best practice for eliminating these problems are as follows
- Start all templates with a @{
- All template text lines need to start with a @:
- Always use @() instead of @
- Put shared code in a DLL or a shared template file
Following these best practices will enable the fast creation of robust Razor templates that will work successfully with other programming languages.