Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



This app uses the Server-side hosting model.

Step 1: Create a Blazor (server-side) web app

  • From the Visual Studio File menu, select New > Project.
  • Search for the ASP.NET Core Web Application template.

  • Click Next, set the project name to BlazorServerSideApplication and click Create.

  • Select Blazor (server-side) and click Create.

  • In Solution Explorer, remove the unnecessary Data folder and the following files from the Pages folder:
    • Pages\Counter.razor
    • Models\FetchData.razor

  • Open Shared\NavMenu.razor and comment out the following lines:
@*<li class="nav-item px-3">
    <NavLink class="nav-link" href="counter">
        <span class="oi oi-plus" aria-hidden="true"></span> Counter
<li class="nav-item px-3">
    <NavLink class="nav-link" href="fetchdata">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data

Step 2: Add the DevExpress XPO ORM package with NuGet

You can install required packages using one of the following approaches:

  • Package Manager Console
    • From the Visual Studio Tools menu, select NuGet Package Manager > Package Manager Console.
    • Make sure Package source is set to All, or DevExpress 19.1 Local and run the following command:
      Install-Package DevExpress.Xpo -Version 19.1


  • NuGet Package Manager
    • In Solution Explorer, right-click the project name and select Manage NuGet Packages.

    • Make sure Package source is set to All, or DevExpress 19.1 Local on the right.
    • In the left top corner under Browse, search for the DevExpress.Xpo package and select its latest version, 19.1, on the right.
    • Click Install on the right and accept all the licenses in the License Acceptance dialogs.

Step 3: Create ORM data model and seed initial data

  • In Solution Explorer, create the DataAccess folder and add the Customer.cs, Order.cs and DemoDataHelper.cs code files.

  • Replace their contents with the code copied from the corresponding files under this shared folder. These files contain the following classes:

    • Customer and Order: form the persistent data model that maps to the corresponding tables in the database.
    • DemoDataHelper: provides the Seed method to create and save initial data in the database. This method will be called at the application startup in the next steps.
  • For more information, see the following:

Step 4: Create helpers for JSON serialization and more

  • In Solution Explorer, create the Helpers folder and add the ApplicationBuilderExtensions.cs and JsonPopulateObjectHelper.cs code files.
  • Replace their contents with the code copied from the corresponding files under this folder. These files contain the following classes:
    • JsonPopulateObjectHelper: provides persistent type JSON serialization and deserialization.
    • ApplicationBuilderExtensions: declares the extension method UseXpoDemoData. It will call DemoDataHelper at the application startup in the next steps.

Step 5: Configure database connection and plug in ORM data model

  • In Startup.cs, modify the Startup.ConfigureServices method to configure Dependency Injection services for JSON serialization, database connection and CRUD operations using XPO. Here is the modified code:
//using BlazorServerSideApplication.Data; //Comment out.
using XpoTutorial;
using Microsoft.Extensions.Configuration;
using BlazorServerSideApplication.Services;

namespace BlazorServerSideApplication {
    public class Startup {
        //Added lines begin.
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        //Added lines end.

        public void ConfigureServices(IServiceCollection services) {
            //Added lines begin.
            //services.AddSingleton<WeatherForecastService>(); // Comment out.
            services.AddScoped<CustomerService>(); // See step 6.
            services.AddScoped<OrderService>(); // See step 6.
            services.AddXpoDefaultUnitOfWork(true, options => options
                    .UseConnectionPool(false) // Remove this line if you use a database server like SQL Server, Oracle, PostgreSql etc.                    
                    .UseAutoCreationOption(DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema) // Remove this line if the database already exists
                    .UseEntityTypes(typeof(Customer), typeof(Order)) // Pass all of your persistent object types to this method.
            //Added lines end.
  • In Startup.cs, modify the Startup.Configure method and add the app.UseXpoDemoData(); call to create sample data discussed in steps 3 and 4. Here is the modified code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
    if(env.IsDevelopment()) {
    else {
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see




    app.UseEndpoints(endpoints => {

    //Added lines begin.
    //Added lines end.
  • In appsettings.json, add the connection string for an in-memory or any other supported data store. Here is the modified code:
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
  "ConnectionStrings": {
    "ImMemoryDataStore": "XpoProvider=InMemoryDataStore;"

Step 6: Manipulate data in services and bind it to Blazor components

  • In Solution Explorer, create the Services folder and add the CustomerService.cs and OrderService.cs code files.

  • Replace their contents with the code copied from the corresponding files under this folder. They contain the CustomerService and OrderService classes with the Get, Add, Update, and Delete API methods that represent CRUD operations with the Customer and Order persistent classes.

    • These services are registered using the services.AddScoped<CustomerService>(); and services.AddScoped<OrderService>(); calls in step 5.
    • The Get and GetCustomerOrders methods return the IQueryable source to load data from the database using LINQ to XPO.
    • With IQueryable and DevExtreme.AspNet.Data, DxDataGrid can use the advanced features of DevExtreme Data Layer.
    • The Add and Update methods use the JsonPopulateObjectHelper class added in step 4 to populate persistent object properties with the request data.
    • The following asynchronous XPO methods are used to implement CRUD operations in these controller methods: Session.GetObjectByKeyAsync, Session.Delete, UnitOfWork.CommitChangesAsync.
  • In the wwwroot folder, create the lib sub-folder. This is to store client-side libraries for DevExpress Blazor and other frameworks during development.

    • Download the bootstrap.min.js and jquery-3.4.1.slim.min.js JavaScript files for Bootstrap 4.1 and jQuery 3.4.1 respectively. You can skip this step if you display modal dialogs without Bootstrap in the next steps.
    • Open, find the "How to create a new project" section and follow steps 2-5 to add DevExpress Blazor into the project.
    • Place the required DevExpress, Bootstrap and jQuery client-side libraries inside the wwwroot/lib sub-folder as follows:

    • In Pages/_Host.cshtml, register DevExpress, Bootstrap and jQuery client-libraries using the script and link elements:
    <environment include="Development">
        <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
        @*//Added lines begin.*@
        <script src="/lib/jquery/jquery-3.4.1.slim.min.js"></script>
        <script src="/lib/bootstrap/bootstrap.min.js"></script>
        @*//Added lines end.*@
    @*//Added lines begin.*@
    <link href="/lib/dx-blazor/dx-blazor.css" rel="stylesheet" />
    <script src="/lib/dx-blazor/dx-blazor.js"></script>
    @*//Added lines end.*@

Step 7: Run and test the app

  • Build and run the application with F5. The web browser should show the Customers list. You can create, edit or delete customers.
  • You can also view and edit their related orders in a separate form.

Known issues

  • The Edit Orders may display 'XXX Wrong YYY data value type: ZZZ' instead of the OrderDate, Freight and other editors different from text boxes.
  • The System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.' error may occur at DevExtreme.AspNet.Data when deleting data under certain circumstances.
  • A new order is always added to the source customer regardless of the Customer editor changes in the edit form.
You can’t perform that action at this time.