Working with Telerik.Reporting 18.1.24.514
in our .Net 8.0
project in Visual Studio 2022.
In our old framework 4.6
project, Our ReportsController.cs was calling into a separate Reports project which contained all the report designs, etc. And front-end Angular component used the telerikReportViewerTemplate.html
viewer.
So, we’ve upgrade our main API project
to .Net 8.0
– but I want the new ReportsController.cs
to call into the old Reports
framework project (i.e. upgrading all the Reports to Telerik v18 Core is a problem regarding the old Telerik Charts lib, which is obsolete now https://docs.telerik.com/reporting/report-items/chart-(obsolete) ).
In the new .Net 8 project, I’m able to set a breakpoint – but the front end always throws an error:
Unable to get report parameters. Report 'SynReports.ReportCatalog' cannot be resolved.
Here’s the .Net 8 ReportsController.cs
using System.Web.Http;
using Telerik.Reporting.Services.WebApi;
using System.Web;
using Telerik.Reporting.Cache.File;
using Telerik.Reporting.Services;
namespace SyneWAPI.Controllers
{
[AllowCrossSiteJson]
[RoutePrefix("api/reports")]
public class ReportsController : ReportsControllerBase
{
static readonly ReportServiceConfiguration configurationInstance =
new ReportServiceConfiguration
{
HostAppId = "HarApp",
ReportSourceResolver = new UriReportSourceResolver(HttpContext.Current.Server.MapPath("~/Reports"))
.AddFallbackResolver(new TypeReportSourceResolver()),
Storage = new FileStorage(),
};
public ReportsController()
{
ReportServiceConfiguration = configurationInstance;
}
}
}
and Program.cs
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json.Serialization;
using Telerik.Reporting.Services;
using Telerik.Reporting.Cache.File;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services
.AddControllers(options =>
{
options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
options.OutputFormatters.RemoveType<StringOutputFormatter>();
})
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();
// TODO: CORS will have to be updated
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.AllowAnyOrigin();
});
});
// Configure dependencies for ReportsController.
builder.Services.TryAddSingleton<IReportServiceConfiguration>(sp =>
new ReportServiceConfiguration
{
ReportingEngineConfiguration = sp.GetService<IConfiguration>(),
HostAppId = "Harmony",
Storage = new FileStorage(),
ReportSourceResolver =
new UriReportSourceResolver(
System.IO.Path.Combine(sp.GetService<IWebHostEnvironment>().ContentRootPath, "~\SynReports")
)
});
builder.Services.AddSwaggerGen(c => {
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.IgnoreObsoleteActions();
c.IgnoreObsoleteProperties();
c.CustomSchemaIds(type => type.FullName);
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//app.UseHttpsRedirection();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
I think the kicker might be this line here: System.IO.Path.Combine(sp.GetService<IWebHostEnvironment>().ContentRootPath, "~\SynReports")
And you can see that SynReport referenced here in the WAPICore project
On the front-end, our stats.component.ts:
export class StatisticsComponent {
currentPatient: any;
serviceUrl: string;
reportSource: any;
telerikTemplateUrl: string;
viewerContainerStyle = {
position: 'relative',
width: '100%',
height: '100%',
['font-family']: 'ms sans serif'
};
constructor(private readonly appSession: AppSession, private readonly config: AppConfigService) {
this.serviceUrl = "https://hardevapp01.topsyn.com/har63/api/reports";
this.telerikTemplateUrl = "assets/templates/telerikReportViewerTemplate-18.1.24.514.html";
this.reportSource = {
report: "SynReports.ReportCatalog",
parameters: {
UserID: "TheUserID",
SessionID: "TheSessionID",
RootUrl: "",
},
};
}
}
The HTML template:
<tr-viewer
[containerStyle]="viewerContainerStyle"
[serviceUrl]="serviceUrl"
[reportSource]="reportSource"
[viewMode]="'INTERACTIVE'"
[scaleMode]="'SPECIFIC'"
[pageMode]="'SINGLE_PAGE'"
[scale]="1.0"
[templateUrl]="telerikTemplateUrl"
[parameters]="{
editors: {
multiSelect: 'COMBO_BOX',
singleSelect: 'COMBO_BOX'
}
}"
>
</tr-viewer>