Search results
Suggest a FeaturePDF

Create ASP.NET Core Web API Service

In this section, you will learn how to create a ASP.NET Core Web API for Report Designer using the new ASP.NET Core Web Application template.

Bold Reports ASP.NET Core supports from .NET Core 2.1 only. So, choose the .NET Core version ASP.NET Core 2.1 or higher versions for Designer API creation.

To get start quickly with ASP.NET Core Web API for Report Designer, you can check on this video:

  1. Start Visual Studio 2022 and click Create new project.
  2. Choose ASP.NET Core Web API, and then click Next. Creating a new ASP.NET Core Application Project
  3. Change the project name, and then click Next.
  4. In the dropdown for the ASP.NET Core version, choose ASP.NET Core 6.0, then click Create. Creating a new ASP.NET Core Application Project

If you need to use Bold Reports with ASP.NET Core on Linux or macOS, then refer to this Can Bold Reports be used with ASP.NET Core on Linux and macOS section.

List of dependency Libraries

The Web API service configuration requires the following reporting server-side packages. In the Solution Explore, right-click the Dependencies, select Manage NuGet Packages and then search the package BoldReports.Net.Core and install to the application. The following provides detail of the packages and its usage.

Package Purpose
BoldReports.Net.Core Builds the server-side implementations.

If we install the above NuGet packages, it automatically add the below ReportDesigner dependent NuGet file in your application.

Package Purpose
Syncfusion.Compression.Net.Core Supports for exporting the report to PDF, Microsoft Word, and Microsoft Excel format. It is a base library for the packages Syncfusion.Pdf.Net.Core , Syncfusion.DocIO.Net.Core and Syncfusion.XlsIO.Net.Core.
Syncfusion.Pdf.Net.Core Supports for exporting the report to a PDF.
Syncfusion.DocIO.Net.Core Supports for exporting the report to a Word.
Syncfusion.XlsIO.Net.Core Supports for exporting the report to an Excel.
Syncfusion.OfficeChart.Net.Core It is a base library of the Syncfusion.XlsIO.Net.Core package.
Newtonsoft.Json Serialize and deserialize the data or report for report designer. It is a mandatory package for the report designer, and the package version should be higher of 10.0.1 for NET Core 2.0 and others should be higher of 9.0.1.
System.Data.SqlClient This is an optional package for the report viewer and designer. It should be referred in project when process the RDL report and which contains the SQL Server and SQL Azure data source. Also, the package version should be higher of 4.1.0 .

Refer to the NuGet Packages section to learn more details about installing and configuring Report Designer NuGet packages.

Register CORS

Browser security prevents Report Designer from making requests to your API Service when both runs in a different domain. To allow access to your API service from a different domain, you must enable cross-origin requests.

Register AddCors in Program.cs to add CORS services to the app’s service container. Replace the following code to allow any origin requests.

    builder.Services.AddCors(o => o.AddPolicy("AllowAllOrigins", builder =>
    {
    builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader();
    }));

    .......
    .......

    app.UseHttpsRedirection();
    app.UseCors();
    app.UseAuthorization();

For more information about CORS, see Configure CORS for API

Add API Service

  1. Right-click the project and select Add > New Item from the context menu.

  2. In the Add New Item dialog, select API Controller class and name it as ReportingAPIController, and then click Add. Adding a new controller to the project

    While adding API Controller class, name it with the suffix Controller that is mandatory.

Configure Web API

The IReportDesignerController interface contains the required actions and helper methods declaration to process the designer file and data actions. The ReportDesignerHelper and ReportHelper class contains methods that help to process Post or Get request from the control and return the response.

Methods Description
PostDesignerAction Action (HttpPost) method for posting the request for designer actions.
UploadReportAction Action (HttpPost) method for posted file actions.
SetData Writes the resource into storage location.
GetData Reads the resource from storage location.
GetImage Action (HttpGet) method for getting resource of images in the report.
PostReportAction Action (HttpPost) method for posting the request for report process.
GetResource Action (HttpGet) method for getting resource for report.
OnInitReportOptions Report initialization method that occurs when the report is about to be processed.
OnReportLoaded Report loaded method that occurs when the report and sub report start loading.

ReportDesignerHelper

The class ReportDesignerHelper contains helper methods that help to process Post or Get request from the Report Designer control and returns the response to the Report Designer control. It has the following methods.

Methods Description
GetResource Returns the report resource for the requested key.
ProcessReport Processes the report request and returns the result.

ReportHelper

The class ReportHelper contains helper methods that help process Post or Get request for report preview action and returns the response to the Report Designer. It has the following methods.

Methods Description
GetResource Returns the report resource for the requested key.
ProcessReport Processes the report request and returns the result.
  1. Open the ReportingAPIController and add the following using statement.

    using BoldReports.Web.ReportViewer;
    using BoldReports.Web.ReportDesigner;
  2. Add the {action} placeholder in the route template, if not contains with default controller attribute.

    [Route("api/[controller]/[action]")]
    public class ReportingAPIController : Controller
    {
    
    }
  3. Next, add the [EnableCors] attribute to the ReportingAPIController class and specify the policy name which given in Startup.ConfigureServices.

    [Microsoft.AspNetCore.Cors.EnableCors("AllowAllOrigins")]
    [Route("api/[controller]/[action]")]
    public class ReportingAPIController : Controller, BoldReports.Web.ReportDesigner.IReportDesignerController
    {
    }
  4. Inherit the IReportDesignerController interface, and implement its methods (replace the following code in newly created Web API controller).

    [Microsoft.AspNetCore.Cors.EnableCors("AllowAllOrigins")]
    [Route("api/[controller]/[action]")]
    public class ReportingAPIController : Controller, BoldReports.Web.ReportDesigner.IReportDesignerController
    {
        private Microsoft.Extensions.Caching.Memory.IMemoryCache _cache;
        private Microsoft.AspNetCore.Hosting.IWebHostEnvironment _hostingEnvironment;
    
        public ReportingAPIController(Microsoft.Extensions.Caching.Memory.IMemoryCache memoryCache, Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment)
        {
            _cache = memoryCache;
            _hostingEnvironment = hostingEnvironment;
        }
    
        /// <summary>
        /// Get the path of specific file
        /// </summary>
        /// <param name="itemName">Name of the file to get the full path</param>
        /// <param name="key">The unique key for report designer</param>
        /// <returns>Returns the full path of file</returns>
        [NonAction]
        private string GetFilePath(string itemName, string key)
        {
            string dirPath = Path.Combine(this._hostingEnvironment.WebRootPath, "Cache", key);
    
            if (!System.IO.Directory.Exists(dirPath))
            {
                System.IO.Directory.CreateDirectory(dirPath);
            }
    
            return Path.Combine(dirPath, itemName);
        }
    
        /// <summary>
        /// Action (HttpGet) method for getting resource of images in the report.
        /// </summary>
        /// <param name="key">The unique key for request identification.</param>
        /// <param name="image">The name of requested image.</param>
        /// <returns>Returns the image as HttpResponseMessage content.</returns>
        public object GetImage(string key, string image)
        {
            return ReportDesignerHelper.GetImage(key, image, this);
        }
    
        /// <summary>
        /// Send a GET request and returns the requested resource for a report.
        /// </summary>
        /// <param name="resource">Contains report resource information.</param>
        /// <returns> Resource object for the given key</returns>
        public object GetResource(ReportResource resource)
        {
            return ReportHelper.GetResource(resource, this, _cache);
        }
    
        [NonAction]
        public void OnInitReportOptions(ReportViewerOptions reportOption)
        {
    
        }
    
        [NonAction]
        public void OnReportLoaded(ReportViewerOptions reportOption)
        {
    
        }
    
        /// <summary>
        /// Action (HttpPost) method for posting the request for designer actions.
        /// </summary>
        /// <param name="jsonResult">A collection of keys and values to process the designer request.</param>
        /// <returns>Json result for the current request.</returns>
        [HttpPost]
        public object PostDesignerAction([FromBody] Dictionary<string, object> jsonResult)
        {
            return ReportDesignerHelper.ProcessDesigner(jsonResult, this, null, this._cache);
        }
    
        public object PostFormDesignerAction()
        {
            return ReportDesignerHelper.ProcessDesigner(null, this, null, this._cache);
        }
    
        public object PostFormReportAction()
        {
            return ReportHelper.ProcessReport(null, this, this._cache);
        }
    
        /// <summary>
        /// Action (HttpPost) method for posting the request for report process.
        /// </summary>
        /// <param name="jsonResult">The JSON data posted for processing report.</param>
        /// <returns>The object data.</returns>
        [HttpPost]
        public object PostReportAction([FromBody] Dictionary<string, object> jsonResult)
        {
            return ReportHelper.ProcessReport(jsonResult, this, this._cache);
        }
    
        /// <summary>
        /// Sets the resource into storage location.
        /// </summary>
        /// <param name="key">The unique key for request identification.</param>
        /// <param name="itemId">The unique key to get the required resource.</param>
        /// <param name="itemData">Contains the resource data.</param>
        /// <param name="errorMessage">Returns the error message, if the write action is failed.</param>
        /// <returns>Returns true, if resource is successfully written into storage location.</returns>
        [NonAction]
        public bool SetData(string key, string itemId, ItemInfo itemData, out string errorMessage)
        {
            errorMessage = string.Empty;
    
            if (itemData.Data != null)
            {
                System.IO.File.WriteAllBytes(this.GetFilePath(itemId, key), itemData.Data);
            }
            else if (itemData.PostedFile != null)
            {
                var fileName = itemId;
                if (string.IsNullOrEmpty(itemId))
                {
                    fileName = System.IO.Path.GetFileName(itemData.PostedFile.FileName);
                }
    
                using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
                {
                    itemData.PostedFile.OpenReadStream().CopyTo(stream);
                    byte[] bytes = stream.ToArray();
                    var writePath = this.GetFilePath(fileName, key);
    
                    System.IO.File.WriteAllBytes(writePath, bytes);
                    stream.Close();
                    stream.Dispose();
                }
            }
            return true;
        }
    
        /// <summary>
        /// Gets the resource from storage location.
        /// </summary>
        /// <param name="key">The unique key for request identification.</param>
        /// <param name="itemId">The unique key to get the required resource.</param>
        ///  <returns>Returns the resource data and error message.</returns>
        [NonAction]
        public ResourceInfo GetData(string key, string itemId)
        {
            var resource = new ResourceInfo();
            try
            {
                var filePath = this.GetFilePath(itemId, key);
                if (itemId.Equals(Path.GetFileName(filePath), StringComparison.InvariantCultureIgnoreCase) && File.Exists(filePath))
                {
                    resource.Data = System.IO.File.ReadAllBytes(filePath);
                }
                else
                {
                    resource.ErrorMessage = "File not found from the specified path";
                }
            }
            catch (Exception ex)
            {
                resource.ErrorMessage = ex.Message;
            }
            return resource;
        }
    
        /// <summary>
        /// Action (HttpPost) method for posted or uploaded file actions.
        /// </summary>
        [HttpPost]
        public void UploadReportAction()
        {
            ReportDesignerHelper.ProcessDesigner(null, this, this.Request.Form.Files[0], this._cache);
        }
    }
  5. Compile and run the Web API service application.