Vazor
Vazor is a VB.NET Razor for ASP.NET Core 6.0 (MVC and Razor Pages)
Install / Use
/learn @VBAndCs/VazorREADME
Vazor 2.0 (Updated to .NET 6)
Copyright (c) 2019-2020 Mohammad Hamdy Ghanem.

Vazor stands for VB.NET Razor. It allows you to write ASP.NET (both MVC Core and Razor Pages) applications with VB.NET including designing the views with vb.net code embedded in XML literals (which VB.NET supports)!
Vazor Story:
Read about Vazor history: how the idea was born, and grown.
Project and Item Templates
To easily crate Vazor apps in VS2019 and VS2022:
Download this VS Extension VazorEx, and Double-click the file VazorEx.vsix to setup these Vazor templates:
- A Vazor project template for ASP.NET MVC Core 6.0 .
- A Vazor project template for ASP.NET Web Pages Core 6.0 .
- A VazorView item template to add a new vazor view (.vazor and .vbxml.vb files) to the MVC project.
- A VazorPage item template to add a new vazor page (.cshtml, .cshtml.vb, and .vbxml.vb files) to the Razor Pages project.
After installation:
- open VS.Net and create a new project. In the search box, write Vazor, and choose one of the 2 vazor project templates.
- In the project created, right-click a folder in solution explorer and select Add/New Item.
- From the dialoge box select VazorView (if this is an MVC project) or VazorPage (if this is a Razor Pages project).
Html5 Auto-Completion in Vazor:
VazorEx also installs an Html5 CompletionProvider.
It provides Html5 auto completion in VB XML literals:
The auto completion is enabled only when XML root is <vbxml> or <zml>:
Dim x = <vbxml>
<!—auto completion for HTML 5 is available here -->
</vbxml>
You can write <% and press Ctrl+space to get this block written for you:
<%= (Function()
Return < />
End Function)( )%>
where you can use conditions or any other vb code to return an html node.
And you can write <( and press Ctrl+space to get this block written for you:
<%= (Iterator Function()
For Each item In Collection
Yield <p><%= item %></p>
Next
End Function)( ) %>
where you can modify it to iterate through your collection and yiled an thml node based on each item in the collection, like filling a list with elements.
A complere Vazor website sample:
eShopOnWeb_VB.NET is a full ASP.NET Core in VB.NET powered by Vazor and ZML.
ZML support:
You can use ZML tags inside vbxml code, and call ParseZML to compile ZML tags to C# Razor code. For more info, see ZML repo.
Vazor Viewes:
Vazor uses xml literals to compose the HTML code, so all you need is to create a class to represent your view, and make it inherit Vazor.VazorView class. You can name the class as you want, but you must pass the view name without any the extension (like "Index", and "_layout") to the Name property by a call to the base class constructor. You can define a field or a property to hold your model data (like a list of students), and receive these data through the constructor of the class. Write the vbxml code that represents the view in the GetVbXml Function. Do not forget that our view is a VB class, and there is no limit to what you can do with it. This is an example of a class to represent the Index View. You will find it in the Index.vazor.vb file:
Imports Microsoft.AspNetCore.Mvc.ViewFeatures
Imports Vazor
Public Class IndexView
Inherits VazorView
Public ReadOnly Property Students As List(Of Student)
Public ReadOnly Property ViewData() As ViewDataDictionary
Public Sub New(students As List(Of Student), viewData As ViewDataDictionary)
MyBase.New("Index", "Views\Home", "Hello")
Me.Students = students
Me.ViewData = viewData
viewData("Title") = Title
End Sub
Public Shared Function CreateNew(Students As List(Of Student), viewData As ViewDataDictionary) As String
Return VazorViewMapper.Add(New IndexView(Students, viewData))
End Function
End Class
note that you need to call the IndexView.CreateNew method and pass it as a parameter to the View method in the action method, like this:
Public Class HomeController : Inherits Controller
Public Function Index() As IActionResult
Return View(IndexView.CreateNew(Students, ViewData), Students)
End Function
'......
End Class
The only step left is to design the view. I separated the vbxml code in a partial class, so the view design is separated from vazor code. You will find this in the Index.vbxml.vb file:
Partial Public Class IndexView
Public overrides Function GetVbXml(view As IndexView) As XElement
Return _
_
<vbxml>
<h3> Browse Students</h3>
<p>Select from <%= view.Students.Count() %> students:</p>
<ul>
<%= (Iterator Function()
For Each std In view.Students
Yield <li><%= std.Name %></li>
Next
End Function)() %>
</ul>
<p>Students details:</p>
<ul>
<li ForEach="m">
Id: <m.Id/><br/>
Name: <m.Name/><br/>
<p>Grade: <m.Grade/></p>
</li>
</ul>
<script>
var x = 5;
document.writeln("students count = <%= view.Students.Count() %>");
</script>
</vbxml>
End Function
End Class
VBXML Code Rules:
In vbxml code you can follow these rules:
- XML literals have only one root. So, it you don't eant to add extra html5 tag to contain the page content, wrap your code in a
<vbxml>tag. - All html tags and their attributes can be represented in XML, but there is no intellisense support for them until now.
- Use Razor conventions and tools, like helper tags, sections, partial views, scripts… etc.
- Use
<%= VBCode %>to insert vb code. - You can use @VBCode, but vb will consider it as a plain text, so you will have no intellisense for it, but it will be evaluated by Razor in runtime. This is why you must use c# syntax for expressions written after the @ symbol.
- Use inline-invoked lambda expression to imbed code blocks, like given in the above sample.
- You can use C# code blocks, but vb will treat them as a plain text with no intellisense or syntax check. They will be compiled by Razor in runtime.
- Instead of using VB Eor Each, you can use Vazor data templates, by adding the ForEach="m" attribute to in the tag you want to repeat for each elemnt in the data model, like this part in the above example:
<ul>
<li ForEach="m">
<p>Id: <m.Id/></p>
<p>Name: <m.Name/></p>
<p>Grade: <m.Grade/></p>
</li>
</ul>
this code will add an <li> element for each student. To make this happen, override the VazorView.Content property and call the extension method ParseTemplate() and pass the students list to it, so it evaluates the template. Add this to the IndexView class:
Public Overrides ReadOnly Property Content() As Byte()
Get
Dim html = GetVbXml().ParseTemplate(students)
Return Encoding.GetBytes(html)
End Get
End Property
If you don't want to use the data template, use the ToHtmlString like this:
Dim html = GetVbXml().ToHtmlString()
Note that the original Content propert written in the VazorView class calls the ParseZml method to allow you to use ZML tangs insid vbxml code.
Public Overridable ReadOnly Property Content() As Byte()
Get
Dim html = GetVbXml().ParseZml
Return Encoding.GetBytes(html)
End Get
End Property
How does Vazor work?
Vazor uses IFileProvider to define a virtual file system that delivers the html content produced by the View class, to Razor, so that Razor thinks it is a cshtml view and complete the job for us! So, Razor resolves the tag helpers, paths, combine the layout and sections, and do all other stuff! So in fact, Vazor is just a bridge between the powerful XML literals in VB.NET, and the powerful flexible Razor Engine! The amazing thing here is that we can have a mixed Vazor/Razor in the same project! This means you can write some views as Vazor classes, and write some others as Razor views and they will integrate an co-work smoothly! This is important to save us unnecessary effort to convert Razor views that doesn't contain any code (like the layout page and View imports pages.. etc) to Vazor classes! I converted the layout to Vazor class in the sample project just to prove that all the parts of it can be handled and work normally. The following image shows the rendered Page resulted from:
- layout and Index as a Vazor classes.
- the rest of the parts (like _viewstart and _viewimports) are Razor cshtml files!

Useing Vazor Views:
- To use Vazor view classes instead of cshtml files, configure the virtual file system by adding this to the Startup.ConfigureServices method. For MVC apps use:
services.AddControllersWithViews(). ' Enable Vazor
AddRazorRuntimeCompilation(
Sub(options) options.FileProviders.Add(New Vazor.VazorVie
