Skip to main content

Report Designer Server-Side Configuration (ASP.NET MVC)

  • 4 minutes to read

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).

Prerequisites

Create a new ASP.NET Reporting MVC project from a template as described in the following help topic: Create an ASP.NET MVC Application with a Report Designer.

Create Custom MVC Controllers

The Invoke action allows cross-domain requests.

Tip

You can override the GetLocalization action to customize localization strings.

Web Document Viewer Controller

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;
    }

}

Report Designer Controller

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");
        }
}

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;
    }
}

Query Builder Controller

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;
    }

}

Create Report Storage

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 {
    // ...
}

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());
}
See Also