Back to Devexpress

Create a Data Source for a Loaded Report in the Blazor Document Viewer

xtrareports-402070-web-reporting-blazor-reporting-web-document-viewer-bind-to-object.md

latest14.3 KB
Original Source

Create a Data Source for a Loaded Report in the Blazor Document Viewer

  • Feb 09, 2026
  • 8 minutes to read

To use Object data sources in your reports, you need to ensure that the data objects are available when the report is loaded.

Overview

The ObjectDataSource class instance serves as an intermediate layer to bind a report to a collection of data items.

The ObjectDataSource instance specifies the type, constructors, methods, and properties of a custom object that generates a collection of data items. A custom object can contain a method that populates the data item collection at runtime or retrieves the data from an external data source.

The ObjectDataSource is serialized in the report definition file (REPX). If you bind a report to a collection of custom objects, the data source information cannot be serialized and you cannot restore the data source when a report is loaded from the REPX file.

To bind a data item collection to a report, implement a custom object that populates the data item collection, create the ObjectDataSource for that object and assign the ObjectDataSource instance to the report’s DataSource property.

View Example: How to Use the Object Data Source in Web Reporting Applications

Create the Object Data Source

The following code creates a custom object ( EmployeeList ) that has a parameterized constructor, the Items property, and the GetData method, which returns a collection of DataItem data objects:

Show EmployeeList

csharp
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
// ...
[DisplayName("Employees")]
public class EmployeeList
{
    public EmployeeList()
    {
        Items = InitializeList();
    }
    public EmployeeList(int noOfItems)
    {

        Items = InitializeList().GetRange(1, noOfItems);
    }
    public List<DataItem> Items { get; set; }

    public List<DataItem> InitializeList()
    {
        return new List<DataItem>() {
            new DataItem(1, 101, "Andrew Fuller", "Dr.", "Vice President, Sales"),
            new DataItem(1, 102, "Anne Dodsworth", "Ms.", "Sales Representative"),
            new DataItem(1, 103, "Michael Suyama", "Mr.", "Sales Representative"),
            new DataItem(1, 104, "Janet Leverling", "Ms.", "Sales Representative"),
            new DataItem(1, 105, "Elliot Komaroff", "Dr.", "Sales Coordinator"),
            new DataItem(2, 201, "Nancy Davolio", "Ms.", "Sales Representative"),
            new DataItem(2, 202, "Steven Buchanan", "Mr.", "Sales Manager"),
            new DataItem(2, 203, "Laura Callahan", "Ms.", "Sales Coordinator"),
            new DataItem(3, 301, "Frédérique Citeaux", "Mr.", "Sales Coordinator"),
            new DataItem(3, 302, "Laurence Lebihan", "Mr.", "Sales Representative"),
            new DataItem(3, 303, "Elizabeth Lincoln", "Ms.", "Sales Manager"),
            new DataItem(3, 304, "Yang Wang", "Mr.", "Sales Representative"),
            new DataItem(4, 401, "Antonio Moreno", "Mr.", "Sales Representative"),
            new DataItem(4, 402, "Thomas Hardy", "Mr.", "Sales Representative"),
            new DataItem(4, 403, "Christina Berglund", "Ms.", "Sales Manager"),
            new DataItem(5, 501, "Alejandra Camino", "Ms.", "Sales Representative"),
            new DataItem(5, 502, "Matti Karttunen", "Mr.", "Sales Representative"),
            new DataItem(5, 503, "Rita Müller", "Mrs.", "Sales Representative"),
        };
    }

    public List<DataItem> GetData(int noOfItems)
    {
        List<DataItem> revertList = new List<DataItem>(Items);
        revertList.Reverse();
        return revertList.Take(noOfItems).ToList();
    }
}
public class DataItem {
    public DataItem(int floor, int office, string personName, string titleOfCourtesy, string title) {
        Floor = floor;
        Office = office;
        PersonName = personName;
        TitleOfCourtesy = titleOfCourtesy;
        Title = title;
    }
    public int Floor { get; set; }
    public int Office { get; set; }
    public string PersonName { get; set; }
    public string TitleOfCourtesy { get; set; }
    public string Title { get; set; }
}
vb
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Linq
' ...
<DisplayName("Employees")>
Public Class EmployeeList
  Public Sub New()
      Items = InitializeList()
  End Sub
  Public Sub New(ByVal noOfItems As Integer)

      Items = InitializeList().GetRange(1, noOfItems)
  End Sub
  Public Property Items() As List(Of DataItem)

  Public Function InitializeList() As List(Of DataItem)
      Return New List(Of DataItem)() From {
          New DataItem(1, 101, "Andrew Fuller", "Dr.", "Vice President, Sales"),
          New DataItem(1, 102, "Anne Dodsworth", "Ms.", "Sales Representative"),
          New DataItem(1, 103, "Michael Suyama", "Mr.", "Sales Representative"),
          New DataItem(1, 104, "Janet Leverling", "Ms.", "Sales Representative"),
          New DataItem(1, 105, "Elliot Komaroff", "Dr.", "Sales Coordinator"),
          New DataItem(2, 201, "Nancy Davolio", "Ms.", "Sales Representative"),
          New DataItem(2, 202, "Steven Buchanan", "Mr.", "Sales Manager"),
          New DataItem(2, 203, "Laura Callahan", "Ms.", "Sales Coordinator"),
          New DataItem(3, 301, "Frédérique Citeaux", "Mr.", "Sales Coordinator"),
          New DataItem(3, 302, "Laurence Lebihan", "Mr.", "Sales Representative"),
          New DataItem(3, 303, "Elizabeth Lincoln", "Ms.", "Sales Manager"),
          New DataItem(3, 304, "Yang Wang", "Mr.", "Sales Representative"),
          New DataItem(4, 401, "Antonio Moreno", "Mr.", "Sales Representative"),
          New DataItem(4, 402, "Thomas Hardy", "Mr.", "Sales Representative"),
          New DataItem(4, 403, "Christina Berglund", "Ms.", "Sales Manager"),
          New DataItem(5, 501, "Alejandra Camino", "Ms.", "Sales Representative"),
          New DataItem(5, 502, "Matti Karttunen", "Mr.", "Sales Representative"),
          New DataItem(5, 503, "Rita Müller", "Mrs.", "Sales Representative")
      }
  End Function

  Public Function GetData(ByVal noOfItems As Integer) As List(Of DataItem)
      Dim revertList As New List(Of DataItem)(Items)
      revertList.Reverse()
      Return revertList.Take(noOfItems).ToList()
  End Function
End Class
Public Class DataItem
  Public Sub New(ByVal floor As Integer, ByVal office As Integer, ByVal personName As String, ByVal titleOfCourtesy As String, ByVal title As String)
      Me.Floor = floor
      Me.Office = office
      Me.PersonName = personName
      Me.TitleOfCourtesy = titleOfCourtesy
      Me.Title = title
  End Sub
  Public Property Floor() As Integer
  Public Property Office() As Integer
  Public Property PersonName() As String
  Public Property TitleOfCourtesy() As String
  Public Property Title() As String
End Class

You can create an object data source that is bound to a parameterized object constructor or the object data source that uses the GetData method.

Bind to the Parameterized Object Constructor

The following code creates an object data source that is bound to the Items property and uses the ObjectDataSource.Constructor property to pass the value to the EmployeeList constructor:

cs
using DevExpress.DataAccess.ObjectBinding;
// ...
        private object CreateObjectDataSource(string reportName)
        {
        // ...
                ObjectDataSource dataSource = new ObjectDataSource();
                dataSource.Name = "EmployeeObjectDS";
                dataSource.DataSource = typeof(Employees.EmployeeList);
                // Specify the parameter's default value.
                var parameter = new Parameter("noOfItems", typeof(int), 7);
                dataSource.Constructor = new ObjectConstructorInfo(parameter);
                dataSource.DataMember = "Items";
                return dataSource;
                // ...
        }
vb
Imports DevExpress.DataAccess.ObjectBinding
' ...
        Private Function CreateObjectDataSource(ByVal reportName As String) As Object
' ...
                    Dim dataSource As New ObjectDataSource()
                    dataSource.Name = "EmployeeObjectDS"
                    dataSource.DataSource = GetType(Employees.EmployeeList)
                    ' Specify the parameter's default value.
                    Dim parameter = New Parameter("noOfItems", GetType(Integer), 7)
                    dataSource.Constructor = New ObjectConstructorInfo(parameter)
                    dataSource.DataMember = "Items"
                    Return dataSource
' ...
        End Function

Bind to a Method

The following code creates an object data source that is bound to the GetData method. The method accepts an argument of the number of items to retrieve.

cs
using DevExpress.DataAccess.ObjectBinding;
// ...
        private object CreateObjectDataSource(string reportName)
        {
        // ...
                ObjectDataSource dataSource = new ObjectDataSource();
                dataSource.Name = "EmployeeObjectDS";
                dataSource.DataSource = typeof(Employees.EmployeeList);
                var parameterNoOfItems = new Parameter("noOfItems", typeof(int), 12);
                dataSource.Parameters.Add(parameterNoOfItems);
                dataSource.Constructor = ObjectConstructorInfo.Default;
                dataSource.DataMember = "GetData";
                return dataSource;
                // ...
        }
vb
Imports DevExpress.DataAccess.ObjectBinding
' ...
        Private Function CreateObjectDataSource(ByVal reportName As String) As Object
' ...
                        Dim dataSource As New ObjectDataSource()
                        dataSource.Name = "EmployeeObjectDS"
                        dataSource.DataSource = GetType(Employees.EmployeeList)
                        Dim parameterNoOfItems = New Parameter("noOfItems", GetType(Integer), 12)
                        dataSource.Parameters.Add(parameterNoOfItems)
                        dataSource.DataMember = "GetData"
                        dataSource.Constructor = ObjectConstructorInfo.Default
                        Return dataSource
' ...
        End Function

Map the Report Parameter to the Data Source Parameter

The following code creates an object data source with a parameter that is bound to the report’s parameterNoOfItems parameter. Users can change the report’s parameter and filter the data retrieved from the data source. Refer to the following topic for instructions on how to specify parameter values for a report: Specify Parameter Values in a Blazor Reporting Application.

cs
using DevExpress.DataAccess.ObjectBinding;
// ...
        private object CreateObjectDataSource(string reportName)
        {
        // ...
                ObjectDataSource dataSource = new ObjectDataSource();
                dataSource.Name = "EmployeeObjectDS";
                dataSource.DataSource = typeof(Employees.EmployeeList);
                // Map data source parameter to report's parameter.
                var parameter = new Parameter()
                {
                    Name = "noOfItems",
                    Type = typeof(DevExpress.DataAccess.Expression),
                    Value = new DevExpress.DataAccess.Expression("?parameterNoOfItems", typeof(int))
                };
                dataSource.Constructor = new ObjectConstructorInfo(parameter);
                dataSource.DataMember = "Items";
                return dataSource;
                // ...
        }
vb
Imports DevExpress.DataAccess.ObjectBinding
' ...
        Private Function CreateObjectDataSource(ByVal reportName As String) As Object
' ...
                        Dim dataSource As New ObjectDataSource()
                        dataSource.Name = "EmployeeObjectDS"
                        dataSource.DataSource = GetType(Employees.EmployeeList)
                        ' Map data source parameter to report's parameter.
                        Dim parameter = New Parameter() With {.Name = "noOfItems", .Type = GetType(DevExpress.DataAccess.Expression), .Value = New DevExpress.DataAccess.Expression("?parameterNoOfItems", GetType(Integer))}
                        dataSource.Constructor = New ObjectConstructorInfo(parameter)
                        dataSource.DataMember = "Items"
                        Return dataSource
' ...
        End Function

Recreate the Data Source for the Loaded Report

The report definition file (REPX file) contains the following ObjectDataSource information: the type of an object used for the object data source, the object’s property or method name used to retrieve data, and the parameters. This information is Base-64 encoded.

When the Document Viewer loads a report, it attempts to recreate the data source and use it to retrieve data. If the object that serves as the data source is not defined or referenced in your project, an attempt to recreate the data source fails. In this situation, you can implement a custom IWebDocumentViewerReportResolver service that assigns a data source to the report before the Document Viewer displays it.

The IWebDocumentViewerReportResolver service receives the report’s name passed to the Document Viewer and uses it to create a report and an object data source, bind the report to the data source, and return the report to the Document Viewer. The service can use the methods described in the previous section to create the object data source.

You should register the service at application startup:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddTransient<IWebDocumentViewerReportResolver, CustomWebDocumentViewerReportResolver>();

var app = builder.Build();