xtrareports-118371-web-reporting-asp-net-mvc-reporting-server-side-configuration-report-designer-server-side-configuration-asp-net-mvc.md
This document describes how to create and configure an ASP.NET MVC application as a server-side solution to use the End-User Web Report Designer in JavaScript:
Note
The complete sample project is available in the following DevExpress Examples repository on GitHub: How to Perform the JavaScript Report Designer Integration (with npm or Yarn package managers).
Create a new ASP.NET Reporting MVC project from a template as described in the following help topic: Use DevExpress Visual Studio Templates to Create an ASP.NET MVC Reporting App with a Report Designer.
The Invoke action allows cross-domain requests.
Tip
You can override the GetLocalization action to customize localization strings.
using DevExpress.Web.Mvc.Controllers;
using System.Web.Mvc;
public class WebDocumentViewerController : WebDocumentViewerApiControllerBase
{
//
// GET: /WebDocumentViewer/
public override ActionResult Invoke()
{
var result = base.Invoke();
// Allow cross-domain requests.
Response.AppendHeader("Access-Control-Allow-Origin", "*");
return result;
}
}
Imports DevExpress.Web.Mvc.Controllers
Imports System.Web.Mvc
Public Class WebDocumentViewerController
Inherits WebDocumentViewerApiControllerBase
'
' GET: /WebDocumentViewer/
Public Overrides Function Invoke() As ActionResult
Dim result = MyBase.Invoke()
' Allow cross-domain requests.
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Return result
End Function
End Class
The ReportDesignerApiControllerBase implementation includes an action to create the Report Designer model. This action uses the ReportDesignerClientSideModelGenerator.GetJsonModelScript method with the following parameters:
(Required) A report identifier (name)
(Optional) Available data sources
(Required) URIs for the reporting controllers’ Invoke actions
using System.Web.Mvc;
using DevExpress.Web.Mvc.Controllers;
using DevExpress.XtraReports.Web.ReportDesigner;
//...
public class ReportDesignerController : ReportDesignerApiControllerBase {
//...
public ActionResult GetReportDesignerModel(string reportUrl) {
Response.AppendHeader("Access-Control-Allow-Origin", "*");
string modelJsonScript =
new ReportDesignerClientSideModelGenerator()
.GetJsonModelScript(
reportUrl, // The URL of a report that is opened in the Report Designer when the application starts.
GetAvailableDataSources(), // Available data sources in the Report Designer that can be added to reports.
"ReportDesigner/Invoke", // The URI path of the controller action that processes requests from the Report Designer.
"WebDocumentViewer/Invoke",// The URI path of the controller action that processes requests from the Web Document Viewer.
"QueryBuilder/Invoke" // The URI path of the controller action that processes requests from the Query Builder.
);
return Content(modelJsonScript, "application/json");
}
}
Imports System.Web.Mvc
Imports DevExpress.Web.Mvc.Controllers
Imports DevExpress.XtraReports.Web.ReportDesigner
'...
Public Class ReportDesignerController
Inherits ReportDesignerApiControllerBase
'...
Public Function GetReportDesignerModel(reportUrl As String) As ActionResult
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Dim modelJsonScript As String = New ReportDesignerClientSideModelGenerator().GetJsonModelScript(
reportUrl, ' The URL of a report that is opened in the Report Designer when the application starts.
Null, ' GetAvailableDataSources(), ' Available data sources in the Report Designer that can be added to reports.
"ReportDesigner/Invoke", ' The URI path of the controller action that processes requests from the Report Designer.
"WebDocumentViewer/Invoke",' The URI path of the controller action that processes requests from the Report Designer.
"QueryBuilder/Invoke") ' The URI path of the controller action that processes requests from the Query Builder.
Return Content(modelJsonScript, "application/json")
End Function
End Class
The GetAvailableDataSources method specified in the model settings above creates data sources for the Report Designer:
using System.Web.Mvc;
using System.Collections.Generic;
using DevExpress.Web.Mvc.Controllers;
using DevExpress.DataAccess.Sql;
public class ReportDesignerController : ReportDesignerApiControllerBase {
// ...
Dictionary<string, object> GetAvailableDataSources() {
var dataSources = new Dictionary<string, object>();
SqlDataSource ds = new SqlDataSource("NWindConnectionString");
var query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("Products");
ds.Queries.Add(query);
ds.RebuildResultSchema();
dataSources.Add("SqlDataSource", ds);
return dataSources;
}
}
Imports System.Web.Mvc
Imports System.Collections.Generic
Imports DevExpress.Web.Mvc.Controllers
Imports DevExpress.DataAccess.Sql
Public Class ReportDesignerController
Inherits ReportDesignerApiControllerBase
' ...
Private Function GetAvailableDataSources() As Dictionary(Of String, Object)
Dim dataSources = New Dictionary(Of String, Object)()
Dim ds As New SqlDataSource("NWindConnectionString")
Dim query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("Products")
ds.Queries.Add(query)
ds.RebuildResultSchema()
dataSources.Add("SqlDataSource", ds)
Return dataSources
End Function
End Class
using DevExpress.Web.Mvc.Controllers;
using System.Web.Mvc;
public class QueryBuilderController : QueryBuilderApiControllerBase
{
//
// GET: /QueryBuilder/
public override ActionResult Invoke()
{
var result = base.Invoke();
// Allow cross-domain requests.
Response.AppendHeader("Access-Control-Allow-Origin", "*");
return result;
}
}
Imports DevExpress.Web.Mvc.Controllers
Imports System.Web.Mvc
Public Class QueryBuilderController
Inherits QueryBuilderApiControllerBase
'
' GET: /QueryBuilder/
Public Overrides Function Invoke() As ActionResult
Dim result = MyBase.Invoke()
' Allow cross-domain requests.
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Return result
End Function
End Class
The project template contains the ReportStorageWebExtension class descendant that implements a server-side report storage.
Note
The template generates a sample storage (a ReportStorageWebExtension descendant) for demonstration purposes only. Create your own implementation for use in production.
using DevExpress.XtraReports.Web.Extensions;
public class MyReportStorage : ReportStorageWebExtension {
// ...
}
Imports DevExpress.XtraReports.Web.Extensions
Public Class MyReportStorage
Inherits ReportStorageWebExtension
' ...
End Class
At application startup, the static ReportStorageWebExtension.RegisterExtensionGlobal method registers the custom web report storage:
using DevExpress.XtraReports.Web.Extensions;
protected void Application_Start() {
// ...
ReportStorageWebExtension.RegisterExtensionGlobal(new MyReportStorage());
}
Imports DevExpress.XtraReports.Web.Extensions
Protected Sub Application_Start()
' ...
ReportStorageWebExtension.RegisterExtensionGlobal(New MyReportStorage())
End Sub
See Also