This sample is a rewrite of the popular BlazingPizza sample into DotVVM.
- Make sure you have installed DotVVM for Visual Studio
-
Open the GitHub repo in Visual Studio or
git clone https://github.com/riganti/dotvvm-samples-blazingpizza.git
-
Right-click the
BlazingPizza.Server
project and select View > View in Browser -
You will see HTTP 404, but it is OK – the
BlazingPizza.Server
project is a REST API without a home page – it only provides data to the app itself -
Right-click
BlazingPizza.App
project and select View > View in Browser
- Differences between DotHTML and Razor syntax
- How to design ViewModels and work with binding contexts
- How to create a simple modal dialog
The syntax of DotVVM views is quite different from the Razor/Blazor approach because of the MVVM (Model-View-ViewModel) pattern.
DotVVM ships with many built-in controls (e.g. <dot:Button ...>
) and uses data-binding expressions (e.g. Text="{value: FirstName}"
instead of @
code blocks.
Here is the list of the most frequent differences:
Razor uses @expression
to print values in the page.
In DotVVM, you can use {{value: expression}}
to do the same thing. In contrast to Razor, you can use only simple expressions without method calls - DotVVM translates these expressions in JavaScript. See the supported expressions for value bindings.
In DotVVM, you can use Visible
property on any HTML element to hide it from the page. It is similar to @if
expressions in Razor.
// Razor
@if (ordersWithStatus.Count == 0)
{
<div class="order-list">
<h2>No orders placed</h2>
</div>
}
// DotVVM
<div class="order-list" Visible="{value: Orders.Count == 0}">
<h2>No orders placed</h2>
</div>
There is also IncludedInPage
property that can be used instead of Visible
. Visible
only hides the element by setting display: none
while IncludedInPage
removes the element from DOM completely.
Instead of using loops to iterate over a collection, DotVVM has the <dot:Repeater>
control which can be data-bound to a collection in the viewmodel.
// Razor
<ul>
@foreach (var topping in pizza.Toppings)
{
<li>+ @topping.Name</li>
}
</ul>
// DotVVM
<dot:Repeater DataSource="{value: Toppings}"
WrapperTagName="ul">
<li>+ {{value: Name}}</li>
</dot:Repeater>
The WrapperTagName
property specifies the name of the HTML element that should wrap the individual items - <ul>
in this case.
The Repeater
also has the EmptyDataTemplate
property that can be used to define content displayed when the collection is empty.
We don't like to use plain hyperlinks to link to other DotVVM pages.
Instead, we encourage you to use <dot:RouteLink>
control - it can specify RouteName
and route parameters. This approach is more resillient to route URL changes.
// Razor
<a href="myorders/@item.Order.OrderId" class="btn btn-success">
Track >
</a>
// DotVVM
<dot:RouteLink RouteName="OrderDetails" Param-id="{value: Order.OrderId}"
class="btn btn-success">
Track >
</dot:RouteLink>
The routes are registered in the DotvvmStartup
file:
config.RouteTable.Add("OrderDetails", "myorders/{id:int}", "Views/OrderDetails.dothtml");
We use command binding to call methods defined in the viewmodel.
// Razor
<button type="button" class="delete-topping"
@onclick="@(() => RemoveTopping(topping))">x</button>
// DotVVM
<dot:Button class="delete-topping"
Click="{command: _root.RemoveTopping(_this)}">x</dot:Button>
Instead of concatenating list of CSS classes on an element, you can use class-something
binding to define conditions indicating whether the CSS class is applied or not.
// Razor
<div class="order-total @(Order.Pizzas.Count > 0 ? "" : "hidden")">
Total: ...
</div>
// DotVVM
<div class="order-total" class-hidden="{value: Order.Pizzas.Count > 0}">
Total: ...
</div>
DotVVM uses the same DataAnnotation attributes like Blazor and other .NET frameworks. You can use <dot:Validator>
or <dot:ValidationSummary>
controls to display validation errors.
// Razor
<InputText @bind-Value="Address.PostalCode" />
<ValidationMessage For="@(() => Address.PostalCode)" />
// DotVVM
<dot:TextBox Text="{value: PostalCode}" />
<dot:Validator Value="{value: PostalCode}" ShowErrorMessageText="true" />
DotVVM validation offers plenty of configuration options and flexibility to add CSS classes, display tooltips, or applying other behaviors for invalid viewmodel properties.