Server-Side Configuration (ASP.NET MVC)

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:

  1. Use the Template Gallery to create a new ASP.NET MVC project. Enable the Report Suite to include all the required resources automatically. Refer to Add a New Report to an ASP.NET MVC Application for a step-by-step tutorial.

    You can also provide a reporting functionality to an existing MVC application. To do this, register the required extensions as described in Manual Integration of ASP.NET MVC Reporting Extensions Into an Existing Project.

  2. Create your custom MVC controllers and inherit them from the following classes:

  3. Override the added controllers' Invoke action to allow cross-domain requests:

    using System.Web.Mvc;
    using DevExpress.Web.Mvc.Controllers;
    //...
    
    public class ReportDesignerController : ReportDesignerApiController {
        //...
        public override ActionResult Invoke() {
            var result = base.Invoke();
            Response.AppendHeader("Access-Control-Allow-Origin", "*");
            return result;
        }
    }
    

    You can additionally override the GetLocalization action in the same way if you need to customize localization strings.

  4. Create the ReportStorageWebExtension class's descendant and override its methods to implement a server-side report storage.

    using DevExpress.XtraReports.Web.Extensions;
    
    public class MyReportStorage : ReportStorageWebExtension {
       // ...
    }
    

    Use the static ReportStorageWebExtension.RegisterExtensionGlobal method at the application's startup to register the custom web report storage.

    using DevExpress.XtraReports.Web.Extensions;
    
    protected void Application_Start() {
        // ...
        ReportStorageWebExtension.RegisterExtensionGlobal(new MyReportStorage());
    }
    
  5. In your ReportDesignerApiController implementation, add an action to create the Report Designer model. In this action, use the ReportDesignerClientSideModelGenerator class and provide the following initialization data:

    • A report URL (required);
    • Available data sources (optional);
    • URIs for reporting controllers' Invoke actions (required).
    using System.Web.Mvc;
    using DevExpress.Web.Mvc.Controllers;
    using DevExpress.XtraReports.Web.ReportDesigner;
    //...
    
    public class ReportDesignerController : ReportDesignerApiController {
        //...
         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");
         }
    }
    
  6. Declare a method that creates data sources for the Report Designer (that is, the GetAvailableDataSources method used at the previous step in the Report Designer model):

    Tip

    Skip this step if you do not need to provide 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 : ReportDesignerApiController {
        // ...
    
        Dictionary<string, object> GetAvailableDataSources() {
            var dataSources = new Dictionary<string, object>();
            SqlDataSource ds = new SqlDataSource("Northwind_Connection");
            var query = SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("Products");
            ds.Queries.Add(query);
            ds.RebuildResultSchema();
            dataSources.Add("SqlDataSource", ds);
            return dataSources;
        }
    }
    

See Also