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 versionASP.NET Core 2.1
or higher versions for Designer API creation.
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.
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.
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
file 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
ReportingAPIController
, and then click Add.
While adding API Controller class, name it with the suffix
Controller
that is mandatory.
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. |
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. |
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. |
Open the ReportingAPIController
and add the following using statement.
using BoldReports.Web.ReportViewer;
using BoldReports.Web.ReportDesigner;
Add the {action}
placeholder in the route template, if not contains with default controller attribute.
[Route("api/[controller]/[action]")]
public class ReportingAPIController : Controller
{
}
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
{
}
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;
}
[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);
}
public object GetImage(string key, string image)
{
return ReportDesignerHelper.GetImage(key, image, this);
}
public object GetResource(ReportResource resource)
{
return ReportHelper.GetResource(resource, this, _cache);
}
[NonAction]
public void OnInitReportOptions(ReportViewerOptions reportOption)
{
}
[NonAction]
public void OnReportLoaded(ReportViewerOptions reportOption)
{
}
[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);
}
[HttpPost]
public object PostReportAction([FromBody] Dictionary<string, object> jsonResult)
{
return ReportHelper.ProcessReport(jsonResult, this, this._cache);
}
[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;
}
[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;
}
[HttpPost]
public void UploadReportAction()
{
ReportDesignerHelper.ProcessDesigner(null, this, this.Request.Form.Files[0], this._cache);
}
}
Compile and run the Web API service application.