xtrareports-devexpress-dot-xtrareports-dot-services.md
Allows you to implement a service that resolves a report name to a report instance.
Namespace : DevExpress.XtraReports.Services
Assembly : DevExpress.XtraReports.v25.2.dll
NuGet Package : DevExpress.Reporting.Core
public interface IReportProvider
Public Interface IReportProvider
You can create a custom service that implements the IReportProvider interface to resolve a string to a report instance. The service works for all methods that obtain a report by its string ID (report URL).
Tip
Use the IReportProvider service to resolve XRSubreport report references if the XRSubreport.ReportSourceUrl property specifies report names.
A custom IReportProvider service has priority over the custom ReportStorageWebExtension service.
Add custom logic to the GetReport method. The method can instantiate and return a report based on the specified ID:
using DevExpress.XtraReports.Services;
using DevExpress.XtraReports.UI;
// ...
public class CustomReportProvider : DevExpress.XtraReports.Services.IReportProvider
{
public XtraReport GetReport(string id, ReportProviderContext context)
{
if (string.IsNullOrEmpty(id))
return null;
switch (id)
{
case "Report1":
return CreateReport1();
// ...
}
return new TestReport();
}
}
Imports DevExpress.XtraReports.Services
Imports DevExpress.XtraReports.UI
' ...
Public Class CustomReportProvider
Implements DevExpress.XtraReports.Services.IReportProvider
Public Function GetReport(ByVal id As String, ByVal context As ReportProviderContext) As XtraReport Implements DevExpress.XtraReports.Services.IReportProvider.GetReport
If String.IsNullOrEmpty(id) Then
Return Nothing
End If
Select Case id
Case "Report1"
Return CreateReport1()
' ...
End Select
Return New TestReport()
End Function
End Class
ASP.NET Web Forms and ASP.NET MVC
Call the DefaultWebDocumentViewerContainer.Register method or the DefaultReportDesignerContainer.Register> method at application startup:
using DevExpress.XtraReports.Services;
// ...
void Application_Start(object sender, EventArgs e) {
// ...
DevExpress.XtraReports.Web.ReportDesigner.DefaultReportDesignerContainer.Register<IReportProvider, CustomReportProvider>();
DevExpress.XtraReports.Web.WebDocumentViewer.DefaultWebDocumentViewerContainer.Register<IReportProvider, CustomReportProvider>();
//...
}
Imports DevExpress.XtraReports.Services
' ...
Private Sub Application_Start(sender As Object, e As EventArgs)
' ...
DevExpress.XtraReports.Web.ReportDesigner.DefaultReportDesignerContainer.Register(Of IReportProvider, CustomReportProvider)()
DevExpress.XtraReports.Web.WebDocumentViewer.DefaultWebDocumentViewerContainer.Register(Of IReportProvider, CustomReportProvider)()
' ...
End Sub
ASP.NET Core
Call the AddScoped method at application startup:
using Microsoft.Extensions.DependencyInjection;
using DevExpress.XtraReports.Services;
var builder = WebApplication.CreateBuilder(args);
services.AddScoped<IReportProvider, CustomReportProvider>();
var app = builder.Build();
Use a custom IReportProvider service when your application does not contain a report storage (the ReportStorageWebExtension implementation) and your reports include subreports.
The report’s definition file (REPX format) cannot contain embedded subreports. Instead, it contains a report name specified in the subreport’s XRSubreport.ReportSourceUrl property. When the main report loads, the report storage service resolves subreport names to report instances. If a report storage service is not available, subreports are not loaded. To address the problem, implement the IReportProvider service that resolves all report names, including names that the subreport’s ReportSourceUrl property specifies.
The following code is the controller’s action in an ASP.NET Core application that generates a document in PDF from a report on the server. The application does not rely on Web Reporting controls.
The report contains two subreports side-by-side. At runtime the controller creates the main report and specifies the subreport’s ReportSourceUrl property. The document generation process calls the custom IReportProvider service to resolve the names in the ReportSourceUrl property and obtain subreports.
using DevExpress.XtraReports.Services;
using DevExpress.XtraReports.UI;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.Design;
using System.IO;
// ...
public IActionResult GetDocument([FromServices] IReportProvider reportProvider)
{
XtraReport report = CreateMainReport();
((IServiceContainer)report).RemoveService(typeof(IReportProvider));
((IServiceContainer)report).AddService(typeof(IReportProvider), reportProvider);
report.CreateDocument();
using (var ms = new MemoryStream())
{
report.ExportToPdf(ms);
return File(ms.ToArray(), "application/pdf");
}
}
private static XtraReport CreateMainReport()
{
var report = new XtraReport();
var detailBand = new DetailBand();
report.Bands.Add(detailBand);
var subreport1 = new XRSubreport()
{
BoundsF = new System.Drawing.RectangleF(0, 0, 300, 80),
ReportSourceUrl = "subReport1"
};
detailBand.Controls.Add(subreport1);
var subreport2 = new XRSubreport()
{
BoundsF = new System.Drawing.RectangleF(310, 0, 300, 80),
ReportSourceUrl = "subReport2"
};
detailBand.Controls.AddRange(new[] { subreport1, subreport2 });
return report;
}
using DevExpress.XtraReports.Services;
using DevExpress.XtraReports.UI;
// ...
public class CustomReportProvider : IReportProvider {
public XtraReport GetReport(string id, ReportProviderContext context) {
if(string.IsNullOrEmpty(id))
return null;
XtraReport rep = new XtraReport();
switch (id)
{
case "subReport1":
rep.LoadLayoutFromXml("SubReport1.repx");
return rep;
case "subReport2":
rep.LoadLayoutFromXml("SubReport2.repx");
return rep;
}
return new PredefinedReports.TestReport();
}
}
using Microsoft.Extensions.DependencyInjection;
using DevExpress.XtraReports.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IReportProvider, CustomReportProvider>();
var app = builder.Build();
Note
Review the Open a Report in ASP.NET Core Application help topic for more information.
See Also