@@ -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
286187public 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