Skip to main content
All docs
V24.2

Migrate WebDocumentViewer from ASP.NET MVC to ASP.NET Core MVC

  • 6 minutes to read

You can migrate WebDocumentViewer customizations to a new .NET application. The viewer’s client-side API is the same regardless of the target platform, so you can migrate customization code to a new app with minimal adjustments. A custom implementation of Document Viewer’s services can also be used in a new application because interface implementation is similar in all web frameworks.

Prerequisites

You may require additional packages to run our Reporting components on Linux or iOS: Use Reporting on Linux.

Important

In .NET 8, the System.Drawing.Common library is compatible with Windows only. An exception is thrown on other platforms. See the following topic for more information: Reporting .NET/.NET Core Limitations.

Create an ASP.NET Core Application

Create a new ASP.NET Core Project. Use Visual Studio or the .NET CLI to create a new project:

dotnet new mvc -o AspNetCoreDocumentViewer

Manage Packages and Libraries

Install NuGet Packages

Reference the following package in your application:

For more information on how to install NuGet packages for DevExpress components, review the following help topic: Choose Between Offline and Online DevExpress NuGet Feeds.

Optional NuGet Packages

Install the following package to bundle and minify our static assets:

Install the following package to use Library Manager (LibMan):

Install npm Packages

Right-click the project in the Solution Explorer and select Add | New Item from the context menu. Add npm Configuration File from the Add New Item dialog.

Open the newly created package.json file, replace its content with the following code, and save the file:

{
    "version": "1.0.0",
    "name": "asp.net",
    "private": true,
    "dependencies": {
        "bootstrap": "^5.3.3",
        "devextreme-dist": "24.2-stable",
        "@devexpress/analytics-core": "24.2-stable",
        "devexpress-reporting": "24.2-stable"
    }
}

Right-click package.json in the Solution Explorer and select Restore Packages. Alternatively, you can execute the following command in the folder that contains the package.json file:

npm install

Bundle Resources (bundleconfig.json)

Create a new JSON file, name it bundleconfig.json, and add it to the project. Open the newly created file, paste the following content, and save the file:

[
    {
    "outputFileName": "wwwroot/css/thirdparty.bundle.css",
    "inputFiles": [
        "node_modules/bootstrap/dist/css/bootstrap.min.css",
        "node_modules/devextreme-dist/css/dx.light.css"
    ],
    "minify": {
        "enabled": false,
        "adjustRelativePaths": false
    }
    },
    {
    "outputFileName": "wwwroot/css/viewer.part.bundle.css",
    "inputFiles": [
        "node_modules/@devexpress/analytics-core/dist/css/dx-analytics.common.css",
        "node_modules/@devexpress/analytics-core/dist/css/dx-analytics.light.css",
        "node_modules/devexpress-reporting/dist/css/dx-webdocumentviewer.css"
    ],
    "minify": {
        "enabled": false,
        "adjustRelativePaths": false
    }
    },

    {
    "outputFileName": "wwwroot/js/thirdparty.bundle.js",
    "inputFiles": [
        "node_modules/jquery/dist/jquery.min.js",
        "node_modules/knockout/build/output/knockout-latest.js",
        "node_modules/bootstrap/dist/js/bootstrap.min.js",
        "node_modules/devextreme-dist/js/dx.all.js",
        ],
    "minify": {
        "enabled": false
    },
    "sourceMap": false
    },
    {
    "outputFileName": "wwwroot/js/viewer.part.bundle.js",
    "inputFiles": [
        "node_modules/@devexpress/analytics-core/dist/js/dx-analytics-core.min.js",
        "node_modules/devexpress-reporting/dist/js/dx-webdocumentviewer.min.js"
        ],
    "minify": {
        "enabled": false
    },
    "sourceMap": false
    }
]

Configure LibMan (libman.json)

Right-click the project in the Solution Explorer and select Manage Client-Side Libraries to open the libman.json file.

Manage Client-Side Libraries

Paste the following content and save the file to add fonts and icons to your application:

{
    "version": "1.0",
    "defaultProvider": "filesystem",
    "libraries": [

    {
        "library": "node_modules/devextreme-dist/css/icons/",
        "destination": "wwwroot/css/icons",
        "files": [
        "dxicons.ttf",
        "dxicons.woff2",
        "dxicons.woff"
        ]
    }
    ]
}

Note

If your application already uses the libraries listed above, remove duplicate library references to ensure they are registered only once.

For more information on LibMan, review the following article: Use LibMan with ASP.NET Core in Visual Studio.

Register Client-Side Scripts

Make sure you register bundle resources. Add the following links to the “Layout.cshtml” page’s head section (the Views | Shared folder):

<head>
    <!--...-->
    <link rel="stylesheet" href="~/css/thirdparty.bundle.css" />
    <script src="~/js/thirdparty.bundle.js"></script>
</head>

Add the following links to the file with the Document Viewer (for example, the “Index.cshtml” file):

<!--...-->
<link rel="stylesheet" href="~/css/viewer.part.bundle.css" />
<script src="~/js/viewer.part.bundle.js"></script>
<!--add WebDocumentViewer-->

Implement Skeleton Loading (Optional)

You can enhance the user experience by rendering the loading animation/placeholder until all JavaScript code is available on the client. Refer to the following topic: Enable the Skeleton Screen in ASP.NET Core Application.

Configure Services on Startup (Program.cs)

All Web Document Viewer services that you register in DefaultWebDocumentViewerContainer for ASP.NET MVC app can be registered in the built-in DI container in ASP.NET Core applications. You can parameterize and inject other services within the constructors of Document Viewer-specific services (for example, IHttpContextAccessor). You do not require to update the signature and definition of services that exist in your legacy ASP.NET MVC app. You can copy the implementation of your custom services to your new application as-is. Note that you can use the dependency-injection concept for all migrated services.

The following code snippet registers the ReportStorageWebExtension service:

ASP.NET MVC
using DevExpress.XtraReports.Web.Extensions;
// ...
void Application_Start(object sender, EventArgs e) {
// ...
    ReportStorageWebExtension.RegisterExtensionGlobal(new CustomReportStorageWebExtension());
// ...
}
ASP.NET Core
using DevExpress.XtraReports.Web.Extensions;
// ...
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>(); 
// ...
var app = builder.Build();

Refer to the following help topic for the service list: Register Services in the Document Viewer in ASP.NET Core Application.

The following code snippet references services required by DevExpress Reporting:

using DevExpress.AspNetCore;
using DevExpress.AspNetCore.Reporting;

var builder = WebApplication.CreateBuilder(args);

// Add services
builder.Services.AddControllersWithViews();
builder.Services.AddDevExpressControls();

builder.Services.ConfigureReportingServices(configurator => {
    configurator.ConfigureWebDocumentViewer(viewerConfigurator => {
        viewerConfigurator.UseCachedReportSourceBuilder();
    });
});

var app = builder.Build();

app.UseDevExpressControls();
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;

app.Run();

Migrate Controller Logic

Replace WebDocumentViewerApiControllerBase for ASP.NET MVC with WebDocumentViewerController for ASP.NET Core.

Note

Some ASP.NET MVC applications can process viewer requests by HTTP handlers registered in the “web.config” file. This option is no longer available.

ASP.NET MVC Controller
using DevExpress.Web.Mvc.Controllers;
using System.Web.Mvc;

namespace ServerSide.Controllers {
    public class WebDocumentViewerController : WebDocumentViewerApiControllerBase {
        public override ActionResult Invoke() {
            var result = base.Invoke();
            // Allow cross-domain requests.
            Response.AppendHeader("Access-Control-Allow-Origin", "*");
            return result;
        }
    }
}
ASP.NET Core Controller
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
using DevExpress.AspNetCore.Reporting.WebDocumentViewer.Native.Services;
// ...
public class CustomWebDocumentViewerController : WebDocumentViewerController {
    public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService) {
        public override Task<IActionResult> Invoke() {
        return base.Invoke();
        }
    }
}

Add a Report

Both .CS and .REPX reports are cross-platform and can be reused in any platform reporting application. Refer to the following topic for information on how to prepare reports for migration: Migrate DevExpress Reports to .NET Applications.

Adjust Views

The following code sample displays the Document Viewer and loads aTestReport (the using directive is correct if the TestReport is created in the Reports folder):

ASP.NET MVC View
@Html.DevExpress().WebDocumentViewer(settings => {
    settings.Name = "WebDocumentViewer1";
}).Bind("TestReport").GetHtml()
ASP.NET Core View
@using DevExpress.AspNetCore
@using AspNetCoreDocumentViewer.Reports

@Html.DevExpress().WebDocumentViewer("DocumentViewer")
    .Height("1000px")
        .Bind(new TestReport())

You can also bind the Document Viewer to the WebDocumentViewerModel instance generated in the controller. Refer to the following topic for more information: Bind to a View Model .

Migrate Client-Side Customization

To handle Client-Side events use the WebDocumentViewerBuilder.ClientSideEvents() method. Check the following documentation for more details on how to use Client-Side API in ASP.NET Core application: Document Viewer Client-Side API.

ASP.NET MVC View
@Html.DevExpress().WebDocumentViewer(settings => {
    settings.Name = "clientInstanceName";
    settings.Height = Unit.Pixel(1000);
    settings.ClientSideEvents.BeforeRender = "onBeforeRender";
}).Bind(new TestReport()).GetHtml()
ASP.NET Core View
@Html.DevExpress().WebDocumentViewer("clientInstanceName")
.ClientSideEvents((e) => e.BeforeRender("onBeforeRender"))
.Height("1000px").Bind(new TestReport())

Useful Resources

The “Reporting Best Practices” repository contains an example application to demonstrate best practices when you design a web reporting application with an ASP.NET Core MVC or ASP.NET Core backend and an Angular frontend.

Review the following help topic for more information: ASP.NET Core and Angular Reporting Best Practices.