Skip to content

Commit 9c15a41

Browse files
committed
resolves aspnetzero/aspnet-zero-core#5014: Updated devexpress reporting angular document
1 parent a16987b commit 9c15a41

File tree

1 file changed

+155
-144
lines changed

1 file changed

+155
-144
lines changed

blog-posts/en/devexpress-reporting-asp-net-zero-angular.md

Lines changed: 155 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -31,140 +31,39 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
3131

3232
*(Design your report as you wish)*
3333

34-
If you add the report using Visual Studio, it will create a report file with `.vsrepx` extension but we need a report with `.repx `extension. So, convert `.vsrepx` report to `.repx` report by following the document below;
34+
### Custom Controllers
3535

36-
[https://docs.devexpress.com/XtraReports/14989/get-started-with-devexpress-reporting/create-a-report-in-visual-studio#convert-vsrepx-files-to-repx](https://docs.devexpress.com/XtraReports/14989/get-started-with-devexpress-reporting/create-a-report-in-visual-studio#convert-vsrepx-files-to-repx)
36+
DevExpress Reporting has some abstract Controller definitions which we must implement. You can create Controllers below in your *.Web.Host project.
3737

38-
## Client Side
39-
40-
1. Go to `package.json` and add following dependencies. (It is located in `angular` project)
41-
42-
```json
43-
dependencies: [
44-
"devextreme": "21.1.3",
45-
"@devexpress/analytics-core": "21.1.3",
46-
"devexpress-reporting": "21.1.3",
47-
]
48-
```
49-
50-
*Note: Version of the nuget and npm packages should match*
51-
52-
2. Create new component named `sample-report`
53-
54-
*sample-report.component.html*
55-
56-
```html
57-
<div [@routerTransition]>
58-
<div class="content d-flex flex-column flex-column-fluid">
59-
<sub-header [title]="'SampleReport' | localize">
60-
</sub-header>
61-
62-
<div [class]="containerClass">
63-
<div class="card card-custom">
64-
<div class="card-body">
65-
<dx-report-viewer [reportUrl]="reportUrl" height="400px">
66-
<dxrv-request-options [invokeAction]="invokeAction" [host]="hostUrl"></dxrv-request-options>
67-
</dx-report-viewer>
68-
</div>
69-
</div>
70-
</div>
71-
</div>
72-
</div>
73-
```
74-
75-
*sample-report.component.ts*
76-
77-
```typescript
78-
import {Component, Injector, OnInit, ViewEncapsulation} from '@angular/core';
79-
import {AppComponentBase} from "@shared/common/app-component-base";
80-
import {appModuleAnimation} from "@shared/animations/routerTransition";
81-
82-
@Component({
83-
selector: 'app-sample-report',
84-
encapsulation: ViewEncapsulation.None,
85-
templateUrl: './sample-report.component.html',
86-
styleUrls: ['./sample-report.component.css',
87-
'../../../../node_modules/jquery-ui/themes/base/all.css',
88-
'../../../../node_modules/devextreme/dist/css/dx.common.css',
89-
'../../../../node_modules/devextreme/dist/css/dx.light.css',
90-
'../../../../node_modules/@devexpress/analytics-core/dist/css/dx-analytics.common.css',
91-
'../../../../node_modules/@devexpress/analytics-core/dist/css/dx-analytics.light.css',
92-
'../../../../node_modules/devexpress-reporting/dist/css/dx-webdocumentviewer.css'
93-
],
94-
animations: [appModuleAnimation()]
95-
})
96-
export class SampleReportComponent extends AppComponentBase implements OnInit {
97-
98-
title = 'DXReportViewerSample';
99-
reportUrl = 'SampleReport';
100-
hostUrl = 'https://localhost:44301/';
101-
invokeAction = 'DXXRDV';
102-
103-
constructor(
104-
injector: Injector
105-
) {
106-
super(injector);
107-
}
108-
109-
ngOnInit(): void {
38+
```csharp
39+
[ApiExplorerSettings(IgnoreApi = true)]
40+
public class CustomWebDocumentViewerController : WebDocumentViewerController, ITransientDependency
41+
{
42+
public CustomWebDocumentViewerController(IWebDocumentViewerMvcControllerService controllerService) : base(controllerService)
43+
{
11044
}
11145
}
112-
```
113-
114-
1. Create `sample-report` module
115-
116-
```typescript
117-
import {NgModule} from '@angular/core';
118-
import {SampleReportRoutingModule} from './sample-report-routing.module';
119-
import {SampleReportComponent} from './sample-report.component';
120-
import {AppSharedModule} from "@app/shared/app-shared.module";
121-
import {AdminSharedModule} from "@app/admin/shared/admin-shared.module";
122-
import {DxReportViewerModule} from "@node_modules/devexpress-reporting-angular";
123-
124-
125-
@NgModule({
126-
declarations: [SampleReportComponent],
127-
imports: [
128-
AppSharedModule,
129-
AdminSharedModule,
130-
SampleReportRoutingModule,
131-
DxReportViewerModule
132-
],
133-
exports:[DxReportViewerModule]
134-
})
135-
export class SampleReportModule {
136-
}
137-
```
13846

139-
```typescript
140-
import {NgModule} from '@angular/core';
141-
import {RouterModule, Routes} from '@angular/router';
142-
import {SampleReportComponent} from './sample-report.component';
143-
144-
const routes: Routes = [{
145-
path: '',
146-
component: SampleReportComponent,
147-
pathMatch: 'full'
148-
}];
149-
150-
@NgModule({
151-
imports: [RouterModule.forChild(routes)],
152-
exports: [RouterModule]
153-
})
154-
export class SampleReportRoutingModule {
47+
[ApiExplorerSettings(IgnoreApi = true)]
48+
public class CustomReportDesignerController : ReportDesignerController, ITransientDependency
49+
{
50+
public CustomReportDesignerController(IReportDesignerMvcControllerService controllerService) : base(controllerService)
51+
{
15552
}
156-
```
157-
158-
2. Add sample report route to `admin-routing.module.ts`
53+
}
15954

160-
```typescript
55+
[ApiExplorerSettings(IgnoreApi = true)]
56+
public class CustomQueryBuilderController : QueryBuilderController, ITransientDependency
57+
{
58+
public CustomQueryBuilderController(IQueryBuilderMvcControllerService controllerService) : base(controllerService)
16159
{
162-
path: 'sample-report',
163-
loadChildren: () => import('./sample-report/sample-report.module').then(m => m.SampleReportModule)
16460
}
165-
```
61+
}
62+
```
63+
64+
### Reports Factory
16665

167-
3. Create a factory class which provides reports by name `ReportsFactory`
66+
Create a factory class which provides reports by name `ReportsFactory`
16867

16968
_ReportsFactory.cs_
17069

@@ -178,7 +77,9 @@ public static class ReportsFactory
17877
}
17978
```
18079

181-
4. Create a class named `CustomReportStorageWebExtension` as seen below
80+
### Custom Report Storage Extension
81+
82+
Create a class named `CustomReportStorageWebExtension` as seen below
18283

18384
_CustomReportStorageWebExtension.cs_
18485

@@ -227,7 +128,7 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
227128
// This method is called only for valid URLs after the IsValidUrl method is called.
228129
try
229130
{
230-
if (Directory.EnumerateFiles(ReportDirectory).Select(Path.GetFileNameWithoutExtension).Contains(url))
131+
if (Directory.EnumerateFiles(ReportDirectory).Select(Path.GetFileName).Contains(url))
231132
{
232133
return File.ReadAllBytes(Path.Combine(ReportDirectory, url + FileExtension));
233134
}
@@ -280,7 +181,7 @@ public class CustomReportStorageWebExtension : DevExpress.XtraReports.Web.Extens
280181
}
281182
```
282183

283-
5. Add `CustomReportStorageWebExtension` to dependency injection
184+
Add `CustomReportStorageWebExtension` to dependency injection
284185

285186
```csharp
286187
public IServiceProvider ConfigureServices(IServiceCollection services)
@@ -289,25 +190,135 @@ public IServiceProvider ConfigureServices(IServiceCollection services)
289190
services.AddScoped<ReportStorageWebExtension, CustomReportStorageWebExtension>();//add this line
290191
```
291192

292-
**Note:** If you get a reference error about `WebDocumentViewerController`, `QueryBuilderController` or `ReportDesignerController`, you can follow the solution below:
193+
## Client Side
194+
195+
1. Go to `package.json` and add following dependencies. (It is located in `angular` project) We have used the version `23.1.6` which is the latest version when this document is created. You can use the latest version.
196+
197+
```json
198+
dependencies: [
199+
"devextreme": "^23.1.6",
200+
"@devexpress/analytics-core": "^23.1.6",
201+
"devexpress-reporting-angular": "^23.1.6"
202+
]
203+
```
204+
205+
*Note: Version of the nuget and npm packages should match*
293206

294-
* Go to you `[YOURAPPNAME]WebHostModule` .
207+
2. Create a folder named `sample-report` under `src\app\admin` folder and then create a new component named `sample-report` as shown below.
295208

296-
* Add following code into `PreInitialize` function
209+
*sample-report.component.html*
297210

298-
```csharp
299-
using DevExpress.AspNetCore.Reporting.QueryBuilder;
300-
using DevExpress.AspNetCore.Reporting.ReportDesigner;
301-
using DevExpress.AspNetCore.Reporting.WebDocumentViewer;
302-
303-
public override void PreInitialize()
304-
{
305-
//...
306-
IocManager.Register(typeof(WebDocumentViewerController), DependencyLifeStyle.Transient);
307-
IocManager.Register(typeof(QueryBuilderController), DependencyLifeStyle.Transient);
308-
IocManager.Register(typeof(ReportDesignerController), DependencyLifeStyle.Transient);
309-
}
310-
```
211+
```html
212+
<div [@routerTransition]>
213+
<div class="content d-flex flex-column flex-column-fluid">
214+
<sub-header [title]="'SampleReport' | localize">
215+
</sub-header>
216+
217+
<div [class]="containerClass">
218+
<div class="card card-custom">
219+
<div class="card-body">
220+
<dx-report-viewer [reportUrl]="reportUrl" height="400px">
221+
<dxrv-request-options [invokeAction]="invokeAction" [host]="hostUrl"></dxrv-request-options>
222+
</dx-report-viewer>
223+
</div>
224+
</div>
225+
</div>
226+
</div>
227+
</div>
228+
```
229+
230+
*sample-report.component.ts*
231+
232+
```typescript
233+
import {Component, Injector, OnInit, ViewEncapsulation} from '@angular/core';
234+
import {AppComponentBase} from "@shared/common/app-component-base";
235+
import {appModuleAnimation} from "@shared/animations/routerTransition";
236+
237+
@Component({
238+
selector: 'app-sample-report',
239+
encapsulation: ViewEncapsulation.None,
240+
templateUrl: './sample-report.component.html',
241+
styleUrls: ['./sample-report.component.css',
242+
'../../../../node_modules/devextreme/dist/css/dx.common.css',
243+
'../../../../node_modules/devextreme/dist/css/dx.light.css',
244+
'../../../../node_modules/@devexpress/analytics-core/dist/css/dx-analytics.common.css',
245+
'../../../../node_modules/@devexpress/analytics-core/dist/css/dx-analytics.light.css',
246+
'../../../../node_modules/devexpress-reporting/dist/css/dx-webdocumentviewer.css'
247+
],
248+
animations: [appModuleAnimation()]
249+
})
250+
export class SampleReportComponent extends AppComponentBase implements OnInit {
251+
252+
title = 'DXReportViewerSample';
253+
reportUrl = 'SampleReport';
254+
hostUrl = 'https://localhost:44301/';
255+
invokeAction = 'DXXRDV';
256+
257+
constructor(
258+
injector: Injector
259+
) {
260+
super(injector);
261+
}
262+
263+
ngOnInit(): void {
264+
}
265+
}
266+
```
267+
268+
3. Create `sample-report` module
269+
270+
```typescript
271+
import {NgModule} from '@angular/core';
272+
import {SampleReportRoutingModule} from './sample-report-routing.module';
273+
import {SampleReportComponent} from './sample-report.component';
274+
import {AppSharedModule} from "@app/shared/app-shared.module";
275+
import {AdminSharedModule} from "@app/admin/shared/admin-shared.module";
276+
import {DxReportViewerModule} from "@node_modules/devexpress-reporting-angular";
277+
278+
279+
@NgModule({
280+
declarations: [SampleReportComponent],
281+
imports: [
282+
AppSharedModule,
283+
AdminSharedModule,
284+
SampleReportRoutingModule,
285+
DxReportViewerModule
286+
],
287+
exports:[DxReportViewerModule]
288+
})
289+
export class SampleReportModule {
290+
}
291+
```
292+
293+
4. Create `sample-report-routing.module.ts` routing module
294+
295+
```typescript
296+
import {NgModule} from '@angular/core';
297+
import {RouterModule, Routes} from '@angular/router';
298+
import {SampleReportComponent} from './sample-report.component';
299+
300+
const routes: Routes = [{
301+
path: '',
302+
component: SampleReportComponent,
303+
pathMatch: 'full'
304+
}];
305+
306+
@NgModule({
307+
imports: [RouterModule.forChild(routes)],
308+
exports: [RouterModule]
309+
})
310+
export class SampleReportRoutingModule {
311+
}
312+
```
313+
314+
5. Add sample report route to `admin-routing.module.ts`
315+
316+
```typescript
317+
{
318+
path: 'sample-report',
319+
loadChildren: () => import('./sample-report/sample-report.module').then(m => m.SampleReportModule)
320+
}
321+
```
311322

312-
You can visit **/App/SampleReport** URL under your website to see your report.
323+
You can also add `sample-report` to navigation menu or you can manually visit `http://localhost:4200/app/admin/sample-report`
313324

0 commit comments

Comments
 (0)