diff --git a/docs/en/Tutorials/Part-1.md b/docs/en/Tutorials/Part-1.md index 835c74385f..a0f970c75f 100644 --- a/docs/en/Tutorials/Part-1.md +++ b/docs/en/Tutorials/Part-1.md @@ -754,8 +754,8 @@ It's end of this part. The final UI of this work is shown as below: It's time to create something visible and usable! There are some tools that we will use when developing ABP Angular frontend application: - [Angular CLI](https://angular.io/cli) will be used to create modules, components and services. -- [NGXS](https://ngxs.gitbook.io/ngxs/) will be used as the state management library. - [Ng Bootstrap](https://ng-bootstrap.github.io/#/home) will be used as the UI component library. +- [ngx-datatable](https://swimlane.gitbook.io/ngx-datatable/) will be used as the datatable library. - [Visual Studio Code](https://code.visualstudio.com/) will be used as the code editor (you can use your favorite editor). #### Install NPM packages @@ -778,26 +778,62 @@ yarn ng generate module book --routing true #### Routing -Open the `app-routing.module.ts` file in `src\app` folder. Add the new `import` and add a route as shown below +Open the `app-routing.module.ts` file in `src\app` folder and add a route as shown below: ```js -import { ApplicationLayoutComponent } from '@abp/ng.theme.basic'; //==> added this line to imports <== - -//...added books path with the below to the routes array +const routes: Routes = [ +// ... +// added a new route to the routes array { path: 'books', - component: ApplicationLayoutComponent, - loadChildren: () => import('./book/book.module').then(m => m.BookModule), - data: { - routes: { - name: '::Menu:Books', - iconClass: 'fas fa-book' - } as ABP.Route - }, + loadChildren: () => import('./book/book.module').then(m => m.BookModule) +}] +``` + +* We added a lazy-loaded route. See the [Lazy-Loading Feature Modules](https://angular.io/guide/lazy-loading-ngmodules#lazy-loading-feature-modules). + +Open the `route.provider.ts` file in `src\app` folder and replace the content as below: + +```js +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { APP_INITIALIZER } from '@angular/core'; + +export const APP_ROUTE_PROVIDER = [ + { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true }, +]; + +function configureRoutes(routes: RoutesService) { + return () => { + routes.add([ + { + path: '/', + name: '::Menu:Home', + iconClass: 'fas fa-home', + order: 1, + layout: eLayoutType.application, + }, + // added below element + { + path: '/books', + name: '::Menu:Books', + iconClass: 'fas fa-book', + order: 101, + layout: eLayoutType.application, + }, + ]); + }; } + ``` -* The `ApplicationLayoutComponent` configuration sets the application layout to the new page. We added the `data` object. The `name` is the menu item name and the `iconClass` is the icon of the menu item. +* We added a new route element to show a navigation element labeled "Books" on the menu. + * `path` is the URL of the route. + * `name` is the menu item name. A Localization key can be passed. + * `iconClass` is the icon of the menu item. + * `order` is the order of the menu item. We define 101 to show the route after the "Administration" item. + * `layout` is the layout of the BooksModule's routes. `eLayoutType.application`, `eLayoutType.account` or `eLayoutType.empty` can be defined. + + #### Book list component @@ -865,35 +901,6 @@ Open the browser and navigate to http://localhost:4200/books. We'll see **book-l ![Initial book list page](./images/bookstore-initial-book-list-page.png) -#### Create BookState - -Run the following command in the terminal to create a new state, named `BooksState`: - -```bash -npx @ngxs/cli --name book --directory src/app/book -``` - -* This command creates `book.state.ts` and `book.actions.ts` files in the `src/app/book/state` folder. See the [NGXS CLI documentation](https://www.ngxs.io/plugins/cli). - -Import the `BookState` to the `app.module.ts` in the `src/app` folder and then add the `BookState` to `forRoot` static method of `NgxsModule` as an array element of the first parameter of the method. - -```js -// ... -import { BookState } from './books/state/book.state'; //<== imported BookState ==> - -@NgModule({ - imports: [ - // other imports - - NgxsModule.forRoot([BookState]), //<== added BookState ==> - - //other imports - ], - // ... -}) -export class AppModule {} -``` - #### Generate proxies ABP CLI provides `generate-proxy` command that generates client proxies for your HTTP APIs to make easy to consume your services from the client side. Before running generate-proxy command, your host must be up and running. See the [CLI documentation](../CLI.md) @@ -910,109 +917,40 @@ The generated files looks like below: ![Generated files](./images/generated-proxies.png) -#### GetBooks Action - -Actions can either be thought of as a command which should trigger something to happen, or as the resulting event of something that has already happened. [See NGXS Actions documentation](https://www.ngxs.io/concepts/actions). - -Open the `book.actions.ts` file in `app/book/state` folder and replace the content below: - -```js -export class GetBooks { - static readonly type = '[Book] Get'; -} -``` - -#### Implement BookState - -Open the `book.state.ts` file in `app/book/state` folder and replace the content below: - -```js -import { PagedResultDto } from '@abp/ng.core'; -import { State, Action, StateContext, Selector } from '@ngxs/store'; -import { GetBooks } from './book.actions'; -import { BookService } from '../services'; -import { tap } from 'rxjs/operators'; -import { Injectable } from '@angular/core'; -import { BookDto } from '../models'; - -export class BookStateModel { - public book: PagedResultDto; -} - -@State({ - name: 'BookState', - defaults: { book: {} } as BookStateModel, -}) -@Injectable() -export class BookState { - @Selector() - static getBooks(state: BookStateModel) { - return state.book.items || []; - } - - constructor(private bookService: BookService) {} - - @Action(GetBooks) - get(ctx: StateContext) { - return this.bookService.getListByInput().pipe( - tap((booksResponse) => { - ctx.patchState({ - book: booksResponse, - }); - }) - ); - } -} -``` - -* We added the book property to BookStateModel model. -* We added the `GetBooks` action that retrieves the book data via `BookService` that generated via ABP CLI and patches the state. -* `NGXS` requires to return the observable without subscribing it in the get function. - #### BookListComponent Open the `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: ```js +import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; import { BookDto, BookType } from '../models'; -import { GetBooks } from '../state/book.actions'; -import { BookState } from '../state/book.state'; +import { BookService } from '../services'; @Component({ selector: 'app-book-list', templateUrl: './book-list.component.html', styleUrls: ['./book-list.component.scss'], + providers: [ListService], }) export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; + book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; - loading = false; - - constructor(private store: Store) {} + constructor(public readonly list: ListService, private bookService: BookService) {} ngOnInit() { - this.get(); - } + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } } ``` - -* We added the `get` function that updates store to get the books. -* See the [Dispatching actions](https://ngxs.gitbook.io/ngxs/concepts/store#dispatching-actions) and [Select](https://ngxs.gitbook.io/ngxs/concepts/select) on the `NGXS` documentation for more information on these `NGXS` features. +* We imported and injected the generated `BookService`. +* We implemented the [ListService](https://docs.abp.io/en/abp/latest/UI/Angular/List-Service)` that is a utility service to provide easy pagination, sorting, and search implementation. Open the `book-list.component.html` file in `app\book\book-list` folder and replace the content as below: @@ -1022,38 +960,31 @@ Open the `book-list.component.html` file in `app\book\book-list` folder and repl
- {%{{{ "::Menu:Books" | abpLocalization }}}%} + {%{{{ '::Menu:Books' | abpLocalization }}}%}
- - - - - {%{{{ "::Name" | abpLocalization }}}%} - {%{{{ "::Type" | abpLocalization }}}%} - {%{{{ "::PublishDate" | abpLocalization }}}%} - {%{{{ "::Price" | abpLocalization }}}%} - - - - - {%{{{ data.name }}}%} - {%{{{ booksType[data.type] }}}%} - {%{{{ data.publishDate | date }}}%} - {%{{{ data.price }}}%} - - + + + + + {%{{{ booksType[row.type] }}}%} + + + + + {%{{{ row.publishDate | date }}}%} + + + + + {%{{{ row.price | currency }}}%} + + +
``` @@ -1074,4 +1005,4 @@ In this tutorial we have applied the rules of official [Angular Style Guide](htt ### Next Part -See the [part 2](part-2.md) for creating, updating and deleting books. +See the [part 2](./Part-2.md) for creating, updating and deleting books. diff --git a/docs/en/Tutorials/Part-2.md b/docs/en/Tutorials/Part-2.md index 8ac9e19615..d296335cfa 100644 --- a/docs/en/Tutorials/Part-2.md +++ b/docs/en/Tutorials/Part-2.md @@ -454,78 +454,50 @@ Run the application and try to delete a book. In this section, you will learn how to create a new modal dialog form to create a new book. -#### State definitions - -Open `book.action.ts` in `app\book\state` folder and replace the content as below: +#### Add a modal to BookListComponent -```js -import { CreateUpdateBookDto } from '../models'; //<== added this line ==> -export class GetBooks { - static readonly type = '[Book] Get'; -} +Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: -// added CreateUpdateBook class -export class CreateUpdateBook { - static readonly type = '[Book] Create Update Book'; - constructor(public payload: CreateUpdateBookDto) { } -} -``` +```js +import { ListService, PagedResultDto } from '@abp/ng.core'; +import { Component, OnInit } from '@angular/core'; +import { BookDto, BookType } from '../models'; +import { BookService } from '../services'; -* We imported the `CreateUpdateBookDto` model and created the `CreateUpdateBook` action. +@Component({ + selector: 'app-book-list', + templateUrl: './book-list.component.html', + styleUrls: ['./book-list.component.scss'], + providers: [ListService], +}) +export class BookListComponent implements OnInit { + book = { items: [], totalCount: 0 } as PagedResultDto; -Open `book.state.ts` file in `app\book\state` folder and replace the content as below: + booksType = BookType; -```js -import { PagedResultDto } from '@abp/ng.core'; -import { State, Action, StateContext, Selector } from '@ngxs/store'; -import { GetBooks, CreateUpdateBook } from './book.actions'; // <== added CreateUpdateBook==> -import { BookService } from '../services'; -import { tap } from 'rxjs/operators'; -import { Injectable } from '@angular/core'; -import { BookDto } from '../models'; + isModalOpen = false; // <== added this line ==> -export class BookStateModel { - public book: PagedResultDto; -} + constructor(public readonly list: ListService, private bookService: BookService) {} -@State({ - name: 'BookState', - defaults: { book: {} } as BookStateModel, -}) -@Injectable() -export class BookState { - @Selector() - static getBooks(state: BookStateModel) { - return state.book.items || []; - } + ngOnInit() { + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - constructor(private bookService: BookService) {} - - @Action(GetBooks) - get(ctx: StateContext) { - return this.bookService.getListByInput().pipe( - tap((bookResponse) => { - ctx.patchState({ - book: bookResponse, - }); - }) - ); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } - // added CreateUpdateBook action listener - @Action(CreateUpdateBook) - save(ctx: StateContext, action: CreateUpdateBook) { - return this.bookService.createByInput(action.payload); + // added createBook method + createBook() { + this.isModalOpen = true; } } ``` -* We imported `CreateUpdateBook` action and defined the `save` method that will listen to a `CreateUpdateBook` action to create a book. - -When the `SaveBook` action dispatched, the save method is being executed. It calls `createByInput` method of the `BookService`. +* We defined a variable called `isModalOpen` and `createBook` method. +* We added the `createBook` method. -#### Add a modal to BookListComponent Open `book-list.component.html` file in `books\book-list` folder and replace the content as below: @@ -534,19 +506,12 @@ Open `book-list.component.html` file in `books\book-list` folder and replace the
-
- {%{{{ '::Menu:Books' | abpLocalization }}}%} -
+
{%{{{ '::Menu:Books' | abpLocalization }}}%}
- +
- @@ -555,47 +520,40 @@ Open `book-list.component.html` file in `books\book-list` folder and replace the
- - - - - {%{{{ "::Name" | abpLocalization }}}%} - {%{{{ "::Type" | abpLocalization }}}%} - {%{{{ "::PublishDate" | abpLocalization }}}%} - {%{{{ "::Price" | abpLocalization }}}%} - - - - - {%{{{ data.name }}}%} - {%{{{ booksType[data.type] }}}%} - {%{{{ data.publishDate | date }}}%} - {%{{{ data.price }}}%} - - + + + + + {%{{{ booksType[row.type] }}}%} + + + + + {%{{{ row.publishDate | date }}}%} + + + + + {%{{{ row.price | currency }}}%} + + +
- -

{%{{{ '::NewBook' | abpLocalization }}}%}

-
+ +

{%{{{ '::NewBook' | abpLocalization }}}%}

+
- + - - - + + +
``` @@ -603,55 +561,6 @@ Open `book-list.component.html` file in `books\book-list` folder and replace the * `abp-modal` is a pre-built component to show modals. While you could use another approach to show a modal, `abp-modal` provides additional benefits. * We added `New book` button to the `AbpContentToolbar`. -Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: - -```js -import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; -import { BookDto, BookType } from '../models'; -import { GetBooks } from '../state/book.actions'; -import { BookState } from '../state/book.state'; - -@Component({ - selector: 'app-book-list', - templateUrl: './book-list.component.html', - styleUrls: ['./book-list.component.scss'], -}) -export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; - - booksType = BookType; - - loading = false; - - isModalOpen = false; // <== added this line ==> - - constructor(private store: Store) {} - - ngOnInit() { - this.get(); - } - - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); - } - - // added createBook method - createBook() { - this.isModalOpen = true; - } -} -``` - -* We added `isModalOpen = false` and `createBook` method. - You can open your browser and click **New book** button to see the new modal. ![Empty modal for new book](./images/bookstore-empty-new-book-modal.png) @@ -663,48 +572,43 @@ You can open your browser and click **New book** button to see the new modal. Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: ```js +import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; import { BookDto, BookType } from '../models'; -import { GetBooks } from '../state/book.actions'; -import { BookState } from '../state/book.state'; +import { BookService } from '../services'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // <== added this line ==> @Component({ selector: 'app-book-list', templateUrl: './book-list.component.html', styleUrls: ['./book-list.component.scss'], + providers: [ListService], }) export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; + book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; - loading = false; - isModalOpen = false; form: FormGroup; // <== added this line ==> - constructor(private store: Store, private fb: FormBuilder) {} // <== added FormBuilder ==> + constructor( + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder // <== injected FormBuilder ==> + ) {} ngOnInit() { - this.get(); - } + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } createBook() { - this.buildForm(); //<== added this line ==> + this.buildForm(); // <== added this line ==> this.isModalOpen = true; } @@ -799,13 +703,10 @@ export class BookModule {} Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: ```js +import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; import { BookDto, BookType } from '../models'; -import { GetBooks } from '../state/book.actions'; -import { BookState } from '../state/book.state'; +import { BookService } from '../services'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; // <== added this line ==> @@ -813,37 +714,34 @@ import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap selector: 'app-book-list', templateUrl: './book-list.component.html', styleUrls: ['./book-list.component.scss'], - providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], // <== added this line ==> + providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], // <== added a provide ==> }) export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; + book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; - //added bookTypeArr array + // <== added bookTypeArr array ==> bookTypeArr = Object.keys(BookType).filter( (bookType) => typeof this.booksType[bookType] === 'number' ); - loading = false; - isModalOpen = false; form: FormGroup; - constructor(private store: Store, private fb: FormBuilder) {} + constructor( + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder + ) {} ngOnInit() { - this.get(); - } + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } createBook() { @@ -884,13 +782,10 @@ Now, you can open your browser to see the changes: Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: ```js +import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; import { BookDto, BookType } from '../models'; -import { GetBooks, CreateUpdateBook } from '../state/book.actions'; // <== added CreateUpdateBook ==> -import { BookState } from '../state/book.state'; +import { BookService } from '../services'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; @@ -898,11 +793,10 @@ import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap selector: 'app-book-list', templateUrl: './book-list.component.html', styleUrls: ['./book-list.component.scss'], - providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], + providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], }) export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; + book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; @@ -910,24 +804,22 @@ export class BookListComponent implements OnInit { (bookType) => typeof this.booksType[bookType] === 'number' ); - loading = false; - isModalOpen = false; form: FormGroup; - constructor(private store: Store, private fb: FormBuilder) {} + constructor( + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder + ) {} ngOnInit() { - this.get(); - } + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } createBook() { @@ -950,19 +842,18 @@ export class BookListComponent implements OnInit { return; } - this.store.dispatch(new CreateUpdateBook(this.form.value)).subscribe(() => { + this.bookService.createByInput(this.form.value).subscribe(() => { this.isModalOpen = false; this.form.reset(); - this.get(); + this.list.get(); }); } } ``` -* We imported `CreateUpdateBook`. * We added `save` method -Open `book-list.component.html` in `app\book\book-list` folder and add the following `abp-button` to save the new book. +Open `book-list.component.html` in `app\book\book-list` folder, find the `` element and replace this element with the following to create a new book. ```html @@ -994,63 +885,24 @@ The final modal UI looks like below: ### Updating a book -#### CreateUpdateBook action - -Open the `book.actions.ts` in `app\book\state` folder and replace the content as below: - -```js -import { CreateUpdateBookDto } from '../models'; - -export class GetBooks { - static readonly type = '[Book] Get'; -} - -export class CreateUpdateBook { - static readonly type = '[Book] Create Update Book'; - constructor(public payload: CreateUpdateBookDto, public id?: string) {} // <== added id parameter ==> -} -``` - -* We added `id` parameter to the `CreateUpdateBook` action's constructor. - -Open the `book.state.ts` in `app\book\state` folder and replace the `save` method as below: - -```js -@Action(CreateUpdateBook) -save(ctx: StateContext, action: CreateUpdateBook) { - if (action.id) { - return this.bookService.updateByIdAndInput(action.payload, action.id); - } else { - return this.bookService.createByInput(action.payload); - } -} -``` - -#### BookListComponent - -Open `book-list.component.ts` in `app\book\book-list` folder and inject `BookService` dependency by adding it to the constructor and add a variable named `selectedBook`. +Open `book-list.component.ts` in `app\book\book-list` folder and add a variable named `selectedBook`. ```js +import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { finalize } from 'rxjs/operators'; import { BookDto, BookType } from '../models'; -import { GetBooks, CreateUpdateBook } from '../state/book.actions'; -import { BookState } from '../state/book.state'; +import { BookService } from '../services'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; -import { BookService } from '../services'; // <== imported BookService ==> @Component({ selector: 'app-book-list', templateUrl: './book-list.component.html', styleUrls: ['./book-list.component.scss'], - providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], + providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], }) export class BookListComponent implements OnInit { - @Select(BookState.getBooks) - books$: Observable; + book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; @@ -1058,26 +910,24 @@ export class BookListComponent implements OnInit { (bookType) => typeof this.booksType[bookType] === 'number' ); - loading = false; - isModalOpen = false; form: FormGroup; selectedBook = {} as BookDto; // <== declared selectedBook ==> - constructor(private store: Store, private fb: FormBuilder, private bookService: BookService) {} //<== injected BookService ==> + constructor( + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder + ) {} ngOnInit() { - this.get(); - } + const bookStreamCreator = (query) => this.bookService.getListByInput(query); - get() { - this.loading = true; - this.store - .dispatch(new GetBooks()) - .pipe(finalize(() => (this.loading = false))) - .subscribe(() => {}); + this.list.hookToQuery(bookStreamCreator).subscribe((response) => { + this.book = response; + }); } // <== this method is replaced ==> @@ -1109,30 +959,31 @@ export class BookListComponent implements OnInit { }); } + // <== this method is replaced ==> save() { if (this.form.invalid) { return; } - //<== added this.selectedBook.id ==> - this.store - .dispatch(new CreateUpdateBook(this.form.value, this.selectedBook.id)) - .subscribe(() => { - this.isModalOpen = false; - this.form.reset(); - this.get(); - }); + // <== added request ==> + const request = this.selectedBook.id + ? this.bookService.updateByIdAndInput(this.form.value, this.selectedBook.id) + : this.bookService.createByInput(this.form.value); + + request.subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + this.list.get(); + }); } } ``` -* We imported `BookService`. * We declared a variable named `selectedBook` as `BookDto`. -* We injected `BookService` to the constructor. `BookService` is being used to retrieve the book data which is being edited. * We added `editBook` method. This method fetches the book with the given `Id` and sets it to `selectedBook` object. * We replaced the `buildForm` method so that it creates the form with the `selectedBook` data. * We replaced the `createBook` method so it sets `selectedBook` to an empty object. -* We added `selectedBook.id` to the constructor of the new `CreateUpdateBook`. +* We replaced the `save` method. #### Add "Actions" dropdown to the table @@ -1140,27 +991,14 @@ Open the `book-list.component.html` in `app\book\book-list` folder and replace ```html
- - - - - {%{{{ "::Actions" | abpLocalization }}}%} - {%{{{ "::Name" | abpLocalization }}}%} - {%{{{ "::Type" | abpLocalization }}}%} - {%{{{ "::PublishDate" | abpLocalization }}}%} - {%{{{ "::Price" | abpLocalization }}}%} - - - - - + + + +
-
- - {%{{{ data.name }}}%} - {%{{{ booksType[data.type] }}}%} - {%{{{ data.publishDate | date }}}%} - {%{{{ data.price }}}%} - -
+
+ + + + + {%{{{ booksType[row.type] }}}%} + + + + + {%{{{ row.publishDate | date }}}%} + + + + + {%{{{ row.price | currency }}}%} + + +
``` -- We added a `th` for the "Actions" column. +- We added a `ngx-datatable-column` for the "Actions" column. - We added `button` with `ngbDropdownToggle` to open actions when clicked the button. - We have used to [NgbDropdown](https://ng-bootstrap.github.io/#/components/dropdown/examples) for the dropdown menu of actions. @@ -1198,7 +1048,7 @@ Open `book-list.component.html` in `app\book\book-list` folder and find the ` -

{%{{{ (selectedBook.id ? 'AbpIdentity::Edit' : '::NewBook' ) | abpLocalization }}}%}

+

{%{{{ (selectedBook.id ? '::Edit' : '::NewBook' ) | abpLocalization }}}%}

``` @@ -1206,81 +1056,9 @@ Open `book-list.component.html` in `app\book\book-list` folder and find the ` -import { BookService } from '../services'; -import { tap } from 'rxjs/operators'; -import { Injectable } from '@angular/core'; -import { BookDto } from '../models'; - -export class BookStateModel { - public book: PagedResultDto; -} - -@State({ - name: 'BookState', - defaults: { book: {} } as BookStateModel, -}) -@Injectable() -export class BookState { - @Selector() - static getBooks(state: BookStateModel) { - return state.book.items || []; - } - - constructor(private bookService: BookService) {} - - @Action(GetBooks) - get(ctx: StateContext) { - return this.bookService.getListByInput().pipe( - tap((booksResponse) => { - ctx.patchState({ - book: booksResponse, - }); - }) - ); - } - - @Action(CreateUpdateBook) - save(ctx: StateContext, action: CreateUpdateBook) { - if (action.id) { - return this.bookService.updateByIdAndInput(action.payload, action.id); - } else { - return this.bookService.createByInput(action.payload); - } - } - - // <== added DeleteBook action listener ==> - @Action(DeleteBook) - delete(ctx: StateContext, action: DeleteBook) { - return this.bookService.deleteById(action.id); - } -} -``` - -- We imported `DeleteBook` . - -- We added `DeleteBook` action listener to the end of the file. - - #### Delete confirmation popup -Open `book-list.component.ts` in`app\book\book-list` folder and inject the `ConfirmationService`. +Open `book-list.component.ts` in `app\book\book-list` folder and inject the `ConfirmationService`. Replace the constructor as below: @@ -1289,11 +1067,11 @@ import { ConfirmationService } from '@abp/ng.theme.shared'; //... constructor( - private store: Store, - private fb: FormBuilder, - private bookService: BookService, - private confirmation: ConfirmationService // <== added this line ==> -) { } + public readonly list: ListService, + private bookService: BookService, + private fb: FormBuilder, + private confirmation: ConfirmationService // <== added this line ==> +) {} ``` * We imported `ConfirmationService`. @@ -1301,28 +1079,24 @@ constructor( See the [Confirmation Popup documentation](https://docs.abp.io/en/abp/latest/UI/Angular/Confirmation-Service) -In the `book-list.component.ts` add a delete method : +In the `book-list.component.ts` add a delete method: ```js -import { GetBooks, CreateUpdateBook, DeleteBook } from '../state/book.actions' ;// <== imported DeleteBook ==> - -import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; //<== imported Confirmation ==> +import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; //<== imported Confirmation namespace ==> //... delete(id: string) { - this.confirmation - .warn('::AreYouSureToDelete', 'AbpAccount::AreYouSure') - .subscribe(status => { - if (status === Confirmation.Status.confirm) { - this.store.dispatch(new DeleteBook(id)).subscribe(() => this.get()); - } - }); + this.confirmation.warn('::AreYouSureToDelete', 'AbpAccount::AreYouSure').subscribe((status) => { + if (status === Confirmation.Status.confirm) { + this.bookService.deleteById(id).subscribe(() => this.list.get()); + } + }); } ``` -The `delete` method shows a confirmation popup and subscribes for the user response. `DeleteBook` action dispatched only if user clicks to the `Yes` button. The confirmation popup looks like below: +The `delete` method shows a confirmation popup and subscribes for the user response. The `deleteById` method of `BookService` called only if user clicks to the `Yes` button. The confirmation popup looks like below: ![bookstore-confirmation-popup](./images/bookstore-confirmation-popup.png) @@ -1335,7 +1109,7 @@ Open `book-list.component.html` in `app\book\book-list` folder and modify the `n ```html
-
diff --git a/docs/en/Tutorials/images/bookstore-actions-buttons.png b/docs/en/Tutorials/images/bookstore-actions-buttons.png index e8243fedc7..f5d8f0870b 100644 Binary files a/docs/en/Tutorials/images/bookstore-actions-buttons.png and b/docs/en/Tutorials/images/bookstore-actions-buttons.png differ diff --git a/docs/en/Tutorials/images/bookstore-angular-file-tree.png b/docs/en/Tutorials/images/bookstore-angular-file-tree.png index ffa8dcd7e2..d921f146fc 100644 Binary files a/docs/en/Tutorials/images/bookstore-angular-file-tree.png and b/docs/en/Tutorials/images/bookstore-angular-file-tree.png differ diff --git a/docs/en/Tutorials/images/bookstore-book-list.png b/docs/en/Tutorials/images/bookstore-book-list.png index d402895c9b..ecdb87c737 100644 Binary files a/docs/en/Tutorials/images/bookstore-book-list.png and b/docs/en/Tutorials/images/bookstore-book-list.png differ diff --git a/docs/en/Tutorials/images/bookstore-confirmation-popup.png b/docs/en/Tutorials/images/bookstore-confirmation-popup.png index a80b180f1c..b17e70638d 100644 Binary files a/docs/en/Tutorials/images/bookstore-confirmation-popup.png and b/docs/en/Tutorials/images/bookstore-confirmation-popup.png differ diff --git a/docs/en/Tutorials/images/bookstore-empty-new-book-modal.png b/docs/en/Tutorials/images/bookstore-empty-new-book-modal.png index 2a02802bb9..f4e969ae22 100644 Binary files a/docs/en/Tutorials/images/bookstore-empty-new-book-modal.png and b/docs/en/Tutorials/images/bookstore-empty-new-book-modal.png differ diff --git a/docs/en/UI/Angular/List-Service.md b/docs/en/UI/Angular/List-Service.md index b3c8571866..900606d725 100644 --- a/docs/en/UI/Angular/List-Service.md +++ b/docs/en/UI/Angular/List-Service.md @@ -53,59 +53,41 @@ class BookComponent { } ``` -> Noticed `list` is `public` and `readonly`? That is because we will use `ListService` properties directly in the component's template. That may be considered as an anti-pattern, but it is much quicker to implement. You can always use public component properties instead. +> Noticed `list` is `public` and `readonly`? That is because we will use `ListService` directly in the component's template. That may be considered as an anti-pattern, but it is much quicker to implement. You can always use public component members to expose the `ListService` instance instead. -Place `ListService` properties into the template like this: +Bind `ListService` to ngx-datatable like this: ```html - - - - - - - {%{{{ '::Name' | abpLocalization }}}%} - - - - - - - - {%{{{ data.name }}}%} - - + + ``` + ## Usage with Observables You may use observables in combination with [AsyncPipe](https://angular.io/guide/observables-in-angular#async-pipe) of Angular instead. Here are some possibilities: -```ts +```js book$ = this.list.hookToQuery(query => this.bookService.getListByInput(query)); ``` ```html - - + + ``` @@ -113,7 +95,7 @@ You may use observables in combination with [AsyncPipe](https://angular.io/guide ...or... -```ts +```js @Select(BookState.getBooks) books$: Observable; @@ -128,32 +110,41 @@ You may use observables in combination with [AsyncPipe](https://angular.io/guide ```html - - + + ``` +> We donot recommend using NGXS store for CRUD pages, unless your application needs to share list information between components or use it later on in another page. + + ## How to Refresh Table on Create/Update/Delete `ListService` exposes a `get` method to trigger a request with the current query. So, basically, whenever a create, update, or delete action resolves, you can call `this.list.get();` and it will call hooked stream creator again. -```ts -this.store.dispatch(new DeleteBook(id)).subscribe(this.list.get); +```js + this.bookService.createByInput(form.value) + .subscribe(() => { + this.list.get(); + + // Other subscription logic here + }); ``` ...or... -```ts -this.bookService.createByInput(form.value) - .subscribe(() => { - this.list.get(); - - // Other subscription logic here - }) +```js + this.store.dispatch(new DeleteBook(id)).subscribe(this.list.get); ``` +> We donot recommend using NGXS store for CRUD pages, unless your application needs to share list information between components or use it later on in another page. + + ## How to Implement Server-Side Search in a Table `ListService` exposes a `filter` property that will trigger a request with the current query and the given search string. All you need to do is to bind it to an input element with two-way binding. @@ -163,3 +154,26 @@ this.bookService.createByInput(form.value) ``` + +## Breaking Change with ABP v3.0 + +We had to modify the `ListService` to make it work with `ngx-datatable`. Previously, the minimum value for `page` property was `1` and you could use it like this: + +```html + + +``` + +As of v3.0, with ngx-datatable, the `page` property has to be set as `0` for inital page. Therefore, if you used `ListService` on your tables before and are going to keep `abp-table`, you need to make the following change: + +```html + + +``` + +**Important Note:** The `abp-table` is not removed, but is deprecated and will be removed in the future. Please consider switching to ngx-datatable. diff --git a/docs/en/UI/Angular/Modifying-the-Menu.md b/docs/en/UI/Angular/Modifying-the-Menu.md index 450a5aecd1..76298e1674 100644 --- a/docs/en/UI/Angular/Modifying-the-Menu.md +++ b/docs/en/UI/Angular/Modifying-the-Menu.md @@ -25,9 +25,99 @@ export const environment = { ## How to Add a Navigation Element +### Via `RoutesService` + +You can add routes to the menu by calling the `add` method of `RoutesService`. It is a singleton service, i.e. provided in root, so you can inject and use it immediately. + +```js +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { Component } from '@angular/core'; + +@Component(/* component metadata */) +export class AppComponent { + constructor(routes: RoutesService) { + routes.add([ + { + path: '/your-path', + name: 'Your navigation', + order: 101, + iconClass: 'fas fa-question-circle', + requiredPolicy: 'permission key here', + layout: eLayoutType.application, + }, + { + path: '/your-path/child', + name: 'Your child navigation', + parentName: 'Your navigation', + order: 1, + requiredPolicy: 'permission key here', + }, + ]); + } +} +``` + +An alternative and probably cleaner way is to use a route provider. First create a provider: + +```js +// route.provider.ts +import { RoutesService, eLayoutType } from '@abp/ng.core'; +import { APP_INITIALIZER } from '@angular/core'; + +export const APP_ROUTE_PROVIDER = [ + { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true }, +]; + +function configureRoutes(routes: RoutesService) { + return () => { + routes.add([ + { + path: '/your-path', + name: 'Your navigation', + requiredPolicy: 'permission key here', + order: 101, + iconClass: 'fas fa-question-circle', + layout: eLayoutType.application, + }, + { + path: '/your-path/child', + name: 'Your child navigation', + parentName: 'Your navigation', + requiredPolicy: 'permission key here', + order: 1, + }, + ]); + }; +} +``` + +...and then in app.module.ts... + +```js +import { NgModule } from '@angular/core'; +import { APP_ROUTE_PROVIDER } from './route.provider'; + +@NgModule({ + providers: [APP_ROUTE_PROVIDER], + // imports, declarations, and bootstrap +}) +export class AppModule {} +``` + +Here is what every property works as: + +- `path` is the absolute path of the navigation element. +- `name` is the label of the navigation element. A localization key or a localization object can be passed. +- `parentName` is a reference to the `name` of the parent route in the menu and is used for creating multi-level menu items. +- `requiredPolicy` is the permission key to access the page. See the [Permission Management document](./Permission-Management.md) +- `order` is the order of the navigation element. "Administration" has an order of `100`, so keep that in mind when ordering top level menu items. +- `iconClass` is the class of the `i` tag, which is placed to the left of the navigation label. +- `layout` defines in which layout the route will be loaded. (default: `eLayoutType.empty`) +- `invisible` makes the item invisible in the menu. (default: `false`) + ### Via `routes` Property in `AppRoutingModule` -You can define your routes by adding `routes` as a child property to `data` property of a route configuration in the `app-routing.module`. The `@abp/ng.core` package organizes your routes and stores them in the `ConfigState`. `ApplicationLayoutComponent` gets routes from store and displays them on the menu. +You can define your routes by adding `routes` as a child property to `data` property of a route configuration in the `app-routing.module`. The `@abp/ng.core` package organizes your routes and stores them in the `RoutesService`. You can add the `routes` property like below: @@ -37,7 +127,7 @@ You can add the `routes` property like below: data: { routes: { name: 'Your navigation', - order: 3, + order: 101, iconClass: 'fas fa-question-circle', requiredPolicy: 'permission key here', children: [ @@ -48,99 +138,77 @@ You can add the `routes` property like below: requiredPolicy: 'permission key here', }, ], - } as ABP.Route, // can be imported from @abp/ng.core - } + }, + }, } ``` -- `name` is the label of the navigation element. A localization key or a localization object can be passed. -- `order` is the order of the navigation element. -- `iconClass` is the class of the `i` tag, which is placed to the left of the navigation label. -- `requiredPolicy` is the permission key to access the page. See the [Permission Management document](./Permission-Management.md) -- `children` is an array and is used for declaring child navigation elements. The child navigation element will be placed as a child route which will be available at `'/your-path/child'` based on the given `path` property. - -After adding the `routes` property as described above, the navigation menu looks like this: - -![navigation-menu-via-app-routing](./images/navigation-menu-via-app-routing.png) - -## Via ConfigState - -The `dispatchAddRoute` method of `ConfigStateService` adds a new navigation element to the menu. +Alternatively, you can do this: ```js -// this.config is instance of ConfigStateService - -const newRoute: ABP.Route = { - name: 'My New Page', - iconClass: 'fa fa-dashboard', - path: 'page', - invisible: false, - order: 2, - requiredPolicy: 'MyProjectName.MyNewPage', -} as Omit; - -this.config.dispatchAddRoute(newRoute); -// returns a state stream which emits after dispatch action is complete -``` - -The `newRoute` will be placed as at root level, i.e. without any parent routes, and its url will be stored as `'/path'`. - -If you want **to add a child route, you can do this:** - -```js -// this.config is instance of ConfigStateService -// eIdentityRouteNames enum can be imported from @abp/ng.identity - -const newRoute: ABP.Route = { - parentName: eIdentityRouteNames.IdentityManagement, - name: 'My New Page', - iconClass: 'fa fa-dashboard', - path: 'page', - invisible: false, - order: 3, - requiredPolicy: 'MyProjectName.MyNewPage' -} as Omit; - -this.config.dispatchAddRoute(newRoute); -// returns a state stream which emits after dispatch action is complete +{ + path: 'your-path', + data: { + routes: [ + { + path: '/your-path', + name: 'Your navigation', + order: 101, + iconClass: 'fas fa-question-circle', + requiredPolicy: 'permission key here', + }, + { + path: '/your-path/child', + name: 'Your child navigation', + parentName: 'Your navigation', + order: 1, + requiredPolicy: 'permission key here', + }, + ] as ABP.Route[], // can be imported from @abp/ng.core + }, +} ``` -The `newRoute` will then be placed as a child of the parent route named `eIdentityRouteNames.IdentityManagement` and its url will be set as `'/identity/page'`. +The advantage of the second method is that you are not bound to the parent/child structure and use any paths you like. -The new route will be added like below: +After adding the `routes` property as described above, the navigation menu looks like this: -![navigation-menu-via-config-state](./images/navigation-menu-via-config-state.png) +![navigation-menu-via-app-routing](./images/navigation-menu-via-app-routing.png) -## How to Patch a Navigation Element +## How to Patch or Remove a Navigation Element -The `dispatchPatchRouteByName` method finds a route by its name and replaces its configuration in the store with the new configuration passed as the second parameter. +The `patch` method of `RoutesService` finds a route by its name and replaces its configuration with the new configuration passed as the second parameter. Similarly, `remove` method finds a route and removes it along with its children. ```js -// this.config is instance of ConfigStateService -// eIdentityRouteNames enum can be imported from @abp/ng.identity +// this.routes is instance of RoutesService +// eThemeSharedRouteNames enum can be imported from @abp/ng.theme.shared + +const dashboardRouteConfig: ABP.Route = { + path: '/dashboard', + name: '::Menu:Dashboard', + parentName: '::Menu:Home', + order: 1, + layout: eLayoutType.application, +}; -const newRouteConfig: Partial = { +const newHomeRouteConfig: Partial = { iconClass: 'fas fa-home', - parentName: eIdentityRouteNames.Administration, + parentName: eThemeSharedRouteNames.Administration, order: 0, - children: [ - { - name: 'Dashboard', - path: 'dashboard', - }, - ], }; -this.config.dispatchPatchRouteByName('::Menu:Home', newRouteConfig); -// returns a state stream which emits after dispatch action is complete +this.routes.add([dashboardRouteConfig]); +this.routes.patch('::Menu:Home', newHomeRouteConfig); +this.routes.remove(['Your navigation']); ``` -* Moved the _Home_ navigation under the _Administration_ dropdown based on given `parentName`. -* Added an icon. -* Specified the order. -* Added a child route named _Dashboard_. +- Moved the _Home_ navigation under the _Administration_ dropdown based on given `parentName`. +- Added an icon to _Home_. +- Specified the order and made _Home_ the first item in list. +- Added a route named _Dashboard_ as a child of _Home_. +- Removed _Your navigation_ along with its child route. -After the patch above, navigation elements looks like below: +After the operations above, the new menu looks like below: ![navigation-menu-after-patching](./images/navigation-menu-after-patching.png) diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs index 7823502013..9cfc748c4e 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using Volo.Abp.Modularity; using Volo.Abp.Quartz; @@ -18,6 +19,11 @@ namespace Volo.Abp.BackgroundWorkers.Quartz context.Services.AddConventionalRegistrar(new AbpQuartzConventionalRegistrar()); } + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(typeof(QuartzPeriodicBackgroundWorkerAdapter<>)); + } + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) { var options = context.ServiceProvider.GetService>().Value; diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorkerAdapter.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorkerAdapter.cs new file mode 100644 index 0000000000..dd6a3019b2 --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorkerAdapter.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.BackgroundWorkers.Quartz +{ + public interface IQuartzBackgroundWorkerAdapter : IQuartzBackgroundWorker + { + void BuildWorker(IBackgroundWorker worker); + } +} diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerAdapter.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerAdapter.cs new file mode 100644 index 0000000000..96cf3988bd --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerAdapter.cs @@ -0,0 +1,88 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using Quartz; +using Volo.Abp.Threading; + +namespace Volo.Abp.BackgroundWorkers.Quartz +{ + public class QuartzPeriodicBackgroundWorkerAdapter : QuartzBackgroundWorkerBase, + IQuartzBackgroundWorkerAdapter + where TWorker : IBackgroundWorker + { + private readonly MethodInfo _doWorkAsyncMethod; + private readonly MethodInfo _doWorkMethod; + + public QuartzPeriodicBackgroundWorkerAdapter() + { + AutoRegister = false; + + _doWorkAsyncMethod = typeof(TWorker).GetMethod("DoWorkAsync", BindingFlags.Instance | BindingFlags.NonPublic); + _doWorkMethod = typeof(TWorker).GetMethod("DoWork", BindingFlags.Instance | BindingFlags.NonPublic); + + } + + public void BuildWorker(IBackgroundWorker worker) + { + int? period; + var workerType = worker.GetType(); + + if (worker is AsyncPeriodicBackgroundWorkerBase || worker is PeriodicBackgroundWorkerBase) + { + if (typeof(TWorker) != worker.GetType()) + { + throw new ArgumentException($"{nameof(worker)} type is different from the generic type"); + } + + var timer = (AbpTimer) worker.GetType().GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker); + period = timer?.Period; + } + else + { + return; + } + + if (period == null) + { + return; + } + + JobDetail = JobBuilder + .Create>() + .WithIdentity(workerType.FullName) + .Build(); + Trigger = TriggerBuilder.Create() + .WithIdentity(workerType.FullName) + .WithSimpleSchedule(builder => builder.WithInterval(TimeSpan.FromMilliseconds(period.Value)).RepeatForever()) + .Build(); + } + + public override async Task Execute(IJobExecutionContext context) + { + var worker = (IBackgroundWorker) ServiceProvider.GetService(typeof(TWorker)); + var workerContext = new PeriodicBackgroundWorkerContext(ServiceProvider); + + switch (worker) + { + case AsyncPeriodicBackgroundWorkerBase asyncWorker: + { + if (_doWorkAsyncMethod != null) + { + await (Task) _doWorkAsyncMethod.Invoke(asyncWorker, new object[] {workerContext}); + } + + break; + } + case PeriodicBackgroundWorkerBase syncWorker: + { + if (_doWorkMethod != null) + { + _doWorkMethod.Invoke(syncWorker, new object[] {workerContext}); + } + + break; + } + } + } + } +} diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs index 35359b1d27..d670c1db98 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using System.Threading.Tasks; using Quartz; using Volo.Abp.DependencyInjection; @@ -50,6 +51,19 @@ namespace Volo.Abp.BackgroundWorkers.Quartz await DefaultScheduleJobAsync(quartzWork); } } + else + { + var adapterType = typeof(QuartzPeriodicBackgroundWorkerAdapter<>).MakeGenericType(worker.GetType()); + + var workerAdapter = Activator.CreateInstance(adapterType) as IQuartzBackgroundWorkerAdapter; + + workerAdapter?.BuildWorker(worker); + + if (workerAdapter?.Trigger != null) + { + await DefaultScheduleJobAsync(workerAdapter); + } + } } protected virtual async Task DefaultScheduleJobAsync(IQuartzBackgroundWorker quartzWork) @@ -66,4 +80,4 @@ namespace Volo.Abp.BackgroundWorkers.Quartz } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs index d148346836..b11e3a54f4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs @@ -55,7 +55,7 @@ namespace Volo.Abp.Cli.Commands var environment = JObject.Parse(environmentJson); apiUrl = environment["apis"]["default"]["url"].ToString(); } - apiUrl += "/api/abp/api-definition?IncludeTypes=true"; + apiUrl = apiUrl.EnsureEndsWith('/') + "api/abp/api-definition?IncludeTypes=true"; var uiFramework = GetUiFramework(commandLineArgs); @@ -469,17 +469,21 @@ namespace Volo.Abp.Cli.Commands if (returnValueType.Contains("<")) { returnValueType = returnValueType.Split('<')[1].Split('>')[0]; + var clrType = Type.GetType(returnValueType, throwOnError: false); + if (clrType != null && TypeHelper.IsPrimitiveExtended(clrType, includeEnums: true)) + { + return null; + } + if (returnValueType.StartsWith("Volo.Abp.Application.Dtos") - || returnValueType.StartsWith("System.Collections") - || returnValueType == "System.String" - || returnValueType == "System.Void" - || returnValueType.Contains("System.Net.HttpStatusCode?") - || returnValueType.Contains("IActionResult") - || returnValueType.Contains("ActionResult") - || returnValueType.Contains("IStringValueType") - || returnValueType.Contains("IValueValidator") - || returnValueType.Contains("Guid") - ) + || returnValueType.StartsWith("System.Collections") + || returnValueType == "System.Void" + || returnValueType.Contains("System.Net.HttpStatusCode?") + || returnValueType.Contains("IActionResult") + || returnValueType.Contains("ActionResult") + || returnValueType.Contains("IStringValueType") + || returnValueType.Contains("IValueValidator") + ) { return null; } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateAppService.cs new file mode 100644 index 0000000000..a5d75b0b4b --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateAppService.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Application.Services +{ + public interface ICreateAppService + : ICreateAppService + { + + } + + public interface ICreateAppService + : IApplicationService + { + Task CreateAsync(TCreateInput input); + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateUpdateAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateUpdateAppService.cs new file mode 100644 index 0000000000..ce3698405c --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICreateUpdateAppService.cs @@ -0,0 +1,21 @@ +namespace Volo.Abp.Application.Services +{ + public interface ICreateUpdateAppService + : ICreateUpdateAppService + { + + } + + public interface ICreateUpdateAppService + : ICreateUpdateAppService + { + + } + + public interface ICreateUpdateAppService + : ICreateAppService, + IUpdateAppService + { + + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs index 12f3b51d11..10f88db22a 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/ICrudAppService.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Volo.Abp.Application.Dtos; namespace Volo.Abp.Application.Services @@ -28,16 +27,10 @@ namespace Volo.Abp.Application.Services } public interface ICrudAppService - : IApplicationService + : IReadOnlyAppService, + ICreateUpdateAppService, + IDeleteAppService { - Task GetAsync(TKey id); - Task> GetListAsync(TGetListInput input); - - Task CreateAsync(TCreateInput input); - - Task UpdateAsync(TKey id, TUpdateInput input); - - Task DeleteAsync(TKey id); } } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IDeleteAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IDeleteAppService.cs new file mode 100644 index 0000000000..50badcead9 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IDeleteAppService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Application.Services +{ + public interface IDeleteAppService : IApplicationService + { + Task DeleteAsync(TKey id); + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IReadOnlyAppService.cs new file mode 100644 index 0000000000..09df0dc9cd --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IReadOnlyAppService.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Volo.Abp.Application.Services +{ + public interface IReadOnlyAppService + : IReadOnlyAppService + { + + } + + public interface IReadOnlyAppService + : IReadOnlyAppService + { + + } + + public interface IReadOnlyAppService + : IApplicationService + { + Task GetAsync(TKey id); + + Task> GetListAsync(TGetListInput input); + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IUpdateAppService.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IUpdateAppService.cs new file mode 100644 index 0000000000..c0904709bf --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Services/IUpdateAppService.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Application.Services +{ + public interface IUpdateAppService + : IUpdateAppService + { + + } + + public interface IUpdateAppService + : IApplicationService + { + Task UpdateAsync(TKey id, TUpdateInput input); + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs index e6f433cad6..11550c456f 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs @@ -1,9 +1,6 @@ using System; -using System.Linq; -using System.Linq.Dynamic.Core; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -using Volo.Abp.Auditing; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.MultiTenancy; @@ -61,17 +58,12 @@ namespace Volo.Abp.Application.Services } public abstract class AbstractKeyCrudAppService - : ApplicationService, + : AbstractKeyReadOnlyAppService, ICrudAppService where TEntity : class, IEntity { - protected IRepository Repository { get; } - protected virtual string GetPolicyName { get; set; } - - protected virtual string GetListPolicyName { get; set; } - protected virtual string CreatePolicyName { get; set; } protected virtual string UpdatePolicyName { get; set; } @@ -79,37 +71,11 @@ namespace Volo.Abp.Application.Services protected virtual string DeletePolicyName { get; set; } protected AbstractKeyCrudAppService(IRepository repository) + : base(repository) { Repository = repository; } - public virtual async Task GetAsync(TKey id) - { - await CheckGetPolicyAsync(); - - var entity = await GetEntityByIdAsync(id); - return MapToGetOutputDto(entity); - } - - public virtual async Task> GetListAsync(TGetListInput input) - { - await CheckGetListPolicyAsync(); - - var query = CreateFilteredQuery(input); - - var totalCount = await AsyncExecuter.CountAsync(query); - - query = ApplySorting(query, input); - query = ApplyPaging(query, input); - - var entities = await AsyncExecuter.ToListAsync(query); - - return new PagedResultDto( - totalCount, - entities.Select(MapToGetListOutputDto).ToList() - ); - } - public virtual async Task CreateAsync(TCreateInput input) { await CheckCreatePolicyAsync(); @@ -144,18 +110,6 @@ namespace Volo.Abp.Application.Services protected abstract Task DeleteByIdAsync(TKey id); - protected abstract Task GetEntityByIdAsync(TKey id); - - protected virtual async Task CheckGetPolicyAsync() - { - await CheckPolicyAsync(GetPolicyName); - } - - protected virtual async Task CheckGetListPolicyAsync() - { - await CheckPolicyAsync(GetListPolicyName); - } - protected virtual async Task CheckCreatePolicyAsync() { await CheckPolicyAsync(CreatePolicyName); @@ -171,101 +125,6 @@ namespace Volo.Abp.Application.Services await CheckPolicyAsync(DeletePolicyName); } - /// - /// Should apply sorting if needed. - /// - /// The query. - /// The input. - protected virtual IQueryable ApplySorting(IQueryable query, TGetListInput input) - { - //Try to sort query if available - if (input is ISortedResultRequest sortInput) - { - if (!sortInput.Sorting.IsNullOrWhiteSpace()) - { - return query.OrderBy(sortInput.Sorting); - } - } - - //IQueryable.Task requires sorting, so we should sort if Take will be used. - if (input is ILimitedResultRequest) - { - return ApplyDefaultSorting(query); - } - - //No sorting - return query; - } - - /// - /// Applies sorting if no sorting specified but a limited result requested. - /// - /// The query. - protected virtual IQueryable ApplyDefaultSorting(IQueryable query) - { - if (typeof(TEntity).IsAssignableTo()) - { - return query.OrderByDescending(e => ((ICreationAuditedObject)e).CreationTime); - } - - throw new AbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyCrudAppService!"); - } - - /// - /// Should apply paging if needed. - /// - /// The query. - /// The input. - protected virtual IQueryable ApplyPaging(IQueryable query, TGetListInput input) - { - //Try to use paging if available - if (input is IPagedResultRequest pagedInput) - { - return query.PageBy(pagedInput); - } - - //Try to limit query result if available - if (input is ILimitedResultRequest limitedInput) - { - return query.Take(limitedInput.MaxResultCount); - } - - //No paging - return query; - } - - /// - /// This method should create based on given input. - /// It should filter query if needed, but should not do sorting or paging. - /// Sorting should be done in and paging should be done in - /// methods. - /// - /// The input. - protected virtual IQueryable CreateFilteredQuery(TGetListInput input) - { - return Repository; - } - - /// - /// Maps to . - /// It uses by default. - /// It can be overriden for custom mapping. - /// - protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity) - { - return ObjectMapper.Map(entity); - } - - /// - /// Maps to . - /// It uses by default. - /// It can be overriden for custom mapping. - /// - protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity) - { - return ObjectMapper.Map(entity); - } - /// /// Maps to to create a new entity. /// It uses by default. @@ -284,18 +143,14 @@ namespace Volo.Abp.Application.Services /// protected virtual void SetIdForGuids(TEntity entity) { - var entityWithGuidId = entity as IEntity; - - if (entityWithGuidId == null || entityWithGuidId.Id != Guid.Empty) + if (entity is IEntity entityWithGuidId && entityWithGuidId.Id == Guid.Empty) { - return; + EntityHelper.TrySetId( + entityWithGuidId, + () => GuidGenerator.Create(), + true + ); } - - EntityHelper.TrySetId( - entityWithGuidId, - () => GuidGenerator.Create(), - true - ); } /// diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs new file mode 100644 index 0000000000..9085434211 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs @@ -0,0 +1,184 @@ +using System; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.Application.Services +{ + public abstract class AbstractKeyReadOnlyAppService + : AbstractKeyReadOnlyAppService + where TEntity : class, IEntity + { + protected AbstractKeyReadOnlyAppService(IReadOnlyRepository repository) + : base(repository) + { + + } + } + + public abstract class AbstractKeyReadOnlyAppService + : AbstractKeyReadOnlyAppService + where TEntity : class, IEntity + { + protected AbstractKeyReadOnlyAppService(IReadOnlyRepository repository) + : base(repository) + { + + } + } + + public abstract class AbstractKeyReadOnlyAppService + : ApplicationService + , IReadOnlyAppService + where TEntity : class, IEntity + { + protected IReadOnlyRepository ReadOnlyRepository { get; } + + protected virtual string GetPolicyName { get; set; } + + protected virtual string GetListPolicyName { get; set; } + + protected AbstractKeyReadOnlyAppService(IReadOnlyRepository repository) + { + ReadOnlyRepository = repository; + } + + public virtual async Task GetAsync(TKey id) + { + await CheckGetPolicyAsync(); + + var entity = await GetEntityByIdAsync(id); + return MapToGetOutputDto(entity); + } + + public virtual async Task> GetListAsync(TGetListInput input) + { + await CheckGetListPolicyAsync(); + + var query = CreateFilteredQuery(input); + + var totalCount = await AsyncExecuter.CountAsync(query); + + query = ApplySorting(query, input); + query = ApplyPaging(query, input); + + var entities = await AsyncExecuter.ToListAsync(query); + + return new PagedResultDto( + totalCount, + entities.Select(MapToGetListOutputDto).ToList() + ); + } + + protected abstract Task GetEntityByIdAsync(TKey id); + + protected virtual async Task CheckGetPolicyAsync() + { + await CheckPolicyAsync(GetPolicyName); + } + + protected virtual async Task CheckGetListPolicyAsync() + { + await CheckPolicyAsync(GetListPolicyName); + } + + /// + /// Should apply sorting if needed. + /// + /// The query. + /// The input. + protected virtual IQueryable ApplySorting(IQueryable query, TGetListInput input) + { + //Try to sort query if available + if (input is ISortedResultRequest sortInput) + { + if (!sortInput.Sorting.IsNullOrWhiteSpace()) + { + return query.OrderBy(sortInput.Sorting); + } + } + + //IQueryable.Task requires sorting, so we should sort if Take will be used. + if (input is ILimitedResultRequest) + { + return ApplyDefaultSorting(query); + } + + //No sorting + return query; + } + + /// + /// Applies sorting if no sorting specified but a limited result requested. + /// + /// The query. + protected virtual IQueryable ApplyDefaultSorting(IQueryable query) + { + if (typeof(TEntity).IsAssignableTo()) + { + return query.OrderByDescending(e => ((ICreationAuditedObject)e).CreationTime); + } + + throw new AbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!"); + } + + /// + /// Should apply paging if needed. + /// + /// The query. + /// The input. + protected virtual IQueryable ApplyPaging(IQueryable query, TGetListInput input) + { + //Try to use paging if available + if (input is IPagedResultRequest pagedInput) + { + return query.PageBy(pagedInput); + } + + //Try to limit query result if available + if (input is ILimitedResultRequest limitedInput) + { + return query.Take(limitedInput.MaxResultCount); + } + + //No paging + return query; + } + + /// + /// This method should create based on given input. + /// It should filter query if needed, but should not do sorting or paging. + /// Sorting should be done in and paging should be done in + /// methods. + /// + /// The input. + protected virtual IQueryable CreateFilteredQuery(TGetListInput input) + { + return ReadOnlyRepository; + } + + /// + /// Maps to . + /// It uses by default. + /// It can be overriden for custom mapping. + /// + protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity) + { + return ObjectMapper.Map(entity); + } + + /// + /// Maps to . + /// It uses by default. + /// It can be overriden for custom mapping. + /// + protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity) + { + return ObjectMapper.Map(entity); + } + } +} diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs index a2af0592a4..7832e8a4ab 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs @@ -70,7 +70,7 @@ namespace Volo.Abp.Application.Services protected new IRepository Repository { get; } protected CrudAppService(IRepository repository) - : base(repository) + : base(repository) { Repository = repository; } diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs new file mode 100644 index 0000000000..d99928126c --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs @@ -0,0 +1,66 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.Application.Services +{ + public abstract class ReadOnlyAppService + : ReadOnlyAppService + where TEntity : class, IEntity + where TEntityDto : IEntityDto + { + protected ReadOnlyAppService(IReadOnlyRepository repository) + : base(repository) + { + + } + } + + public abstract class ReadOnlyAppService + : ReadOnlyAppService + where TEntity : class, IEntity + where TEntityDto : IEntityDto + { + protected ReadOnlyAppService(IReadOnlyRepository repository) + : base(repository) + { + + } + } + + public abstract class ReadOnlyAppService + : AbstractKeyReadOnlyAppService + where TEntity : class, IEntity + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto + { + protected new IReadOnlyRepository Repository { get; } + + protected ReadOnlyAppService(IReadOnlyRepository repository) + : base(repository) + { + Repository = repository; + } + + protected override async Task GetEntityByIdAsync(TKey id) + { + return await Repository.GetAsync(id); + } + + protected override IQueryable ApplyDefaultSorting(IQueryable query) + { + if (typeof(TEntity).IsAssignableTo()) + { + return query.OrderByDescending(e => ((ICreationAuditedObject)e).CreationTime); + } + else + { + return query.OrderByDescending(e => e.Id); + } + } + } +} diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj b/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj index f3a0fefb2a..b4aa55b1c0 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj @@ -17,6 +17,7 @@ + diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemOptions.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemOptions.cs index c4a4d203d2..aff1aee4e9 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemOptions.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemOptions.cs @@ -3,7 +3,7 @@ public class AbpVirtualFileSystemOptions { public VirtualFileSetList FileSets { get; } - + public AbpVirtualFileSystemOptions() { FileSets = new VirtualFileSetList(); diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/AbpEmbeddedFileProvider.cs similarity index 81% rename from framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs rename to framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/AbpEmbeddedFileProvider.cs index d2a0556527..ae0acafe09 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/AbpEmbeddedFileProvider.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.FileProviders; namespace Volo.Abp.VirtualFileSystem.Embedded { - public class EmbeddedFileSet : IVirtualFileSet + public class AbpEmbeddedFileProvider : DictionaryBasedFileProvider { [NotNull] public Assembly Assembly { get; } @@ -16,19 +16,22 @@ namespace Volo.Abp.VirtualFileSystem.Embedded [CanBeNull] public string BaseNamespace { get; } - [CanBeNull] - public string BaseFolderInProject { get; } + protected override IDictionary Files => _files.Value; + private readonly Lazy> _files; - public EmbeddedFileSet( + public AbpEmbeddedFileProvider( [NotNull] Assembly assembly, - [CanBeNull] string baseNamespace = null, - [CanBeNull] string baseFolderInProject = null) + [CanBeNull] string baseNamespace = null) { Check.NotNull(assembly, nameof(assembly)); Assembly = assembly; BaseNamespace = baseNamespace; - BaseFolderInProject = baseFolderInProject; + + _files = new Lazy>( + CreateFiles, + true + ); } public void AddFiles(Dictionary files) @@ -127,5 +130,17 @@ namespace Volo.Abp.VirtualFileSystem.Embedded return filePath.Substring(filePath.LastIndexOf("/", StringComparison.Ordinal) + 1); } + + protected override string NormalizePath(string subpath) + { + return VirtualFilePathHelper.NormalizePath(subpath); + } + + private Dictionary CreateFiles() + { + var files = new Dictionary(StringComparer.OrdinalIgnoreCase); + AddFiles(files); + return files; + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedVirtualFileSetInfo.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedVirtualFileSetInfo.cs new file mode 100644 index 0000000000..9f4d87d783 --- /dev/null +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedVirtualFileSetInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem.Embedded +{ + public class EmbeddedVirtualFileSetInfo : VirtualFileSetInfo + { + public Assembly Assembly { get; } + + public string BaseFolder { get; } + + public EmbeddedVirtualFileSetInfo( + IFileProvider fileProvider, + Assembly assembly, + string baseFolder = null) + : base(fileProvider) + { + Assembly = assembly; + BaseFolder = baseFolder; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs deleted file mode 100644 index 1880165d02..0000000000 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; -using Microsoft.Extensions.FileProviders; - -namespace Volo.Abp.VirtualFileSystem -{ - public interface IVirtualFileSet - { - void AddFiles(Dictionary files); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Physical/PhysicalVirtualFileSetInfo.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Physical/PhysicalVirtualFileSetInfo.cs new file mode 100644 index 0000000000..525fa178d6 --- /dev/null +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Physical/PhysicalVirtualFileSetInfo.cs @@ -0,0 +1,19 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem.Physical +{ + public class PhysicalVirtualFileSetInfo : VirtualFileSetInfo + { + public string Root { get; } + + public PhysicalVirtualFileSetInfo( + [NotNull] IFileProvider fileProvider, + [NotNull] string root + ) + : base(fileProvider) + { + Root = Check.NotNullOrWhiteSpace(root, nameof(root)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFilePathHelper.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFilePathHelper.cs index 03f851a7e3..47900d5aa9 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFilePathHelper.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFilePathHelper.cs @@ -6,8 +6,6 @@ namespace Volo.Abp.VirtualFileSystem { internal static class VirtualFilePathHelper { - //TODO: Optimize this class! - public static string NormalizePath(string fullPath) { if (fullPath.Equals("/", StringComparison.Ordinal)) diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs index 5f90ef7925..eb4cd4e415 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; @@ -28,6 +27,11 @@ namespace Volo.Abp.VirtualFileSystem public virtual IDirectoryContents GetDirectoryContents(string subpath) { + if (subpath == "") + { + subpath = "/"; + } + return _hybridFileProvider.GetDirectoryContents(subpath); } @@ -42,52 +46,12 @@ namespace Volo.Abp.VirtualFileSystem fileProviders.Add(dynamicFileProvider); - if (_options.FileSets.PhysicalPaths.Any()) + foreach (var fileSet in _options.FileSets.AsEnumerable().Reverse()) { - fileProviders.AddRange( - _options.FileSets.PhysicalPaths - .Select(rootPath => new PhysicalFileProvider(rootPath)) - .Reverse() - ); + fileProviders.Add(fileSet.FileProvider); } - fileProviders.Add(new InternalVirtualFileProvider(_options)); - return new CompositeFileProvider(fileProviders); } - - protected class InternalVirtualFileProvider : DictionaryBasedFileProvider - { - protected override IDictionary Files => _files.Value; - - private readonly AbpVirtualFileSystemOptions _options; - private readonly Lazy> _files; - - public InternalVirtualFileProvider(AbpVirtualFileSystemOptions options) - { - _options = options; - _files = new Lazy>( - CreateFiles, - true - ); - } - - private Dictionary CreateFiles() - { - var files = new Dictionary(StringComparer.OrdinalIgnoreCase); - - foreach (var set in _options.FileSets) - { - set.AddFiles(files); - } - - return files; - } - - protected override string NormalizePath(string subpath) - { - return VirtualFilePathHelper.NormalizePath(subpath); - } - } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetInfo.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetInfo.cs new file mode 100644 index 0000000000..694729f02a --- /dev/null +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetInfo.cs @@ -0,0 +1,15 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem +{ + public class VirtualFileSetInfo + { + public IFileProvider FileProvider { get; } + + public VirtualFileSetInfo([NotNull] IFileProvider fileProvider) + { + FileProvider = Check.NotNull(fileProvider, nameof(fileProvider)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetList.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetList.cs index 2ddd0ff3a4..371f8350d8 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetList.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetList.cs @@ -2,13 +2,8 @@ namespace Volo.Abp.VirtualFileSystem { - public class VirtualFileSetList : List + public class VirtualFileSetList : List { - public List PhysicalPaths { get; } - - public VirtualFileSetList() - { - PhysicalPaths = new List(); - } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs index 399f76f408..f1ca9749ea 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs @@ -1,44 +1,90 @@ using System; using System.IO; -using System.Linq; +using System.Reflection; using JetBrains.Annotations; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.FileProviders.Physical; using Volo.Abp.VirtualFileSystem.Embedded; +using Volo.Abp.VirtualFileSystem.Physical; namespace Volo.Abp.VirtualFileSystem { public static class VirtualFileSetListExtensions { - public static void AddEmbedded([NotNull] this VirtualFileSetList list, [CanBeNull] string baseNamespace = null, string baseFolderInProject = null) + public static void AddEmbedded( + [NotNull] this VirtualFileSetList list, + [CanBeNull] string baseNamespace = null, + [CanBeNull] string baseFolder = null) { Check.NotNull(list, nameof(list)); - list.Add( - new EmbeddedFileSet( - typeof(T).Assembly, - baseNamespace, - baseFolderInProject - ) + var assembly = typeof(T).Assembly; + var fileProvider = CreateFileProvider( + assembly, + baseNamespace, + baseFolder ); + + list.Add(new EmbeddedVirtualFileSetInfo(fileProvider, assembly, baseFolder)); } - public static void ReplaceEmbeddedByPhysical([NotNull] this VirtualFileSetList list, [NotNull] string pyhsicalPath) + public static void AddPhysical( + [NotNull] this VirtualFileSetList list, + [NotNull] string root, + ExclusionFilters exclusionFilters = ExclusionFilters.Sensitive) { Check.NotNull(list, nameof(list)); - Check.NotNull(pyhsicalPath, nameof(pyhsicalPath)); + Check.NotNullOrWhiteSpace(root, nameof(root)); - var assembly = typeof(T).Assembly; - var embeddedFileSets = list.OfType().Where(fs => fs.Assembly == assembly).ToList(); + var fileProvider = new PhysicalFileProvider(root, exclusionFilters); + list.Add(new PhysicalVirtualFileSetInfo(fileProvider, root)); + } + + private static IFileProvider CreateFileProvider( + [NotNull] Assembly assembly, + [CanBeNull] string baseNamespace = null, + [CanBeNull] string baseFolder = null) + { + Check.NotNull(assembly, nameof(assembly)); - foreach (var embeddedFileSet in embeddedFileSets) + var info = assembly.GetManifestResourceInfo("Microsoft.Extensions.FileProviders.Embedded.Manifest.xml"); + + if (info == null) { - list.Remove(embeddedFileSet); + return new AbpEmbeddedFileProvider(assembly, baseNamespace); + } + + if (baseFolder == null) + { + return new ManifestEmbeddedFileProvider(assembly); + } - if (!embeddedFileSet.BaseFolderInProject.IsNullOrEmpty()) + return new ManifestEmbeddedFileProvider(assembly, baseFolder); + } + + public static void ReplaceEmbeddedByPhysical( + [NotNull] this VirtualFileSetList fileSets, + [NotNull] string physicalPath) + { + Check.NotNull(fileSets, nameof(fileSets)); + Check.NotNullOrWhiteSpace(physicalPath, nameof(physicalPath)); + + var assembly = typeof(T).Assembly; + + for (var i = 0; i < fileSets.Count; i++) + { + if (fileSets[i] is EmbeddedVirtualFileSetInfo embeddedVirtualFileSet && + embeddedVirtualFileSet.Assembly == assembly) { - pyhsicalPath = Path.Combine(pyhsicalPath, embeddedFileSet.BaseFolderInProject); - } + var thisPath = physicalPath; - list.PhysicalPaths.Add(pyhsicalPath); + if (!embeddedVirtualFileSet.BaseFolder.IsNullOrEmpty()) + { + thisPath = Path.Combine(thisPath, embeddedVirtualFileSet.BaseFolder); + } + + fileSets[i] = new PhysicalVirtualFileSetInfo(new PhysicalFileProvider(thisPath), thisPath); + } } } } diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj index 9f8f904aa4..bcb9dcbf74 100644 --- a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj @@ -4,6 +4,7 @@ netcoreapp3.1 + true @@ -15,6 +16,7 @@ + diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/my{test}.2.9.min.js b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/my{test}.2.9.min.js new file mode 100644 index 0000000000..1c74f24545 --- /dev/null +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/my{test}.2.9.min.js @@ -0,0 +1 @@ +//my{test}.2.9.min.js-content \ No newline at end of file diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs index 2243d9a11a..aae01ff912 100644 --- a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using System.Linq; using System.Text; using Microsoft.Extensions.DependencyInjection; @@ -34,6 +33,22 @@ namespace Volo.Abp.VirtualFileSystem Encoding.UTF8.GetString(stream.GetAllBytes()).ShouldBe("//jquery-3-1-1-min.js-contents"); } } + + [Fact] + public void Should_Define_And_Get_Embedded_Resources_With_Special_Chars() + { + //Act + var resource = _virtualFileProvider.GetFileInfo("/js/my{test}.2.9.min.js"); + + //Assert + resource.ShouldNotBeNull(); + resource.Exists.ShouldBeTrue(); + + using (var stream = resource.CreateReadStream()) + { + Encoding.UTF8.GetString(stream.GetAllBytes()).ShouldBe("//my{test}.2.9.min.js-content"); + } + } [Fact] public void Should_Define_And_Get_Embedded_Directory_Contents() @@ -45,7 +60,9 @@ namespace Volo.Abp.VirtualFileSystem contents.Exists.ShouldNotBeNull(); var contentList = contents.ToList(); + contentList.ShouldContain(x => x.Name == "jquery-3-1-1-min.js"); + contentList.ShouldContain(x => x.Name == "my{test}.2.9.min.js"); } [Theory] @@ -70,7 +87,9 @@ namespace Volo.Abp.VirtualFileSystem { Configure(options => { - options.FileSets.AddEmbedded("Volo.Abp.VirtualFileSystem.MyResources"); + options.FileSets.AddEmbedded( + baseFolder: "/Volo/Abp/VirtualFileSystem/MyResources" + ); }); } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs index 86652aacec..5f1967804e 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs @@ -2,10 +2,19 @@ { public class AuditLogActionConsts { - public const int MaxServiceNameLength = 256; + /// + /// Default value: 256 + /// + public static int MaxServiceNameLength { get; set; } = 256; - public const int MaxMethodNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxMethodNameLength { get; set; } = 128; - public const int MaxParametersLength = 2000; + /// + /// Default value: 2000 + /// + public static int MaxParametersLength { get; set; } = 2000; } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs index 504e7451e0..4a8c723b76 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs @@ -2,31 +2,67 @@ { public static class AuditLogConsts { - public const int MaxApplicationNameLength = 96; + /// + /// Default value: 96 + /// + public static int MaxApplicationNameLength { get; set; } = 96; - public const int MaxClientIpAddressLength = 64; + /// + /// Default value: 64 + /// + public static int MaxClientIpAddressLength { get; set; } = 64; - public const int MaxClientNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxClientNameLength { get; set; } = 128; - public const int MaxClientIdLength = 64; + /// + /// Default value: 64 + /// + public static int MaxClientIdLength { get; set; } = 64; - public const int MaxCorrelationIdLength = 64; + /// + /// Default value: 64 + /// + public static int MaxCorrelationIdLength { get; set; } = 64; - public const int MaxBrowserInfoLength = 512; + /// + /// Default value: 512 + /// + public static int MaxBrowserInfoLength { get; set; } = 512; - public const int MaxExceptionsLength = 4000; + /// + /// Default value: 4000 + /// + public static int MaxExceptionsLength { get; set; } = 4000; //TODO: Replace with MaxExceptionsLength in v3.0 public static int MaxExceptionsLengthValue { get; set; } = MaxExceptionsLength; - public const int MaxCommentsLength = 256; + /// + /// Default value: 256 + /// + public static int MaxCommentsLength { get; set; } = 256; - public const int MaxUrlLength = 256; + /// + /// Default value: 256 + /// + public static int MaxUrlLength { get; set; } = 256; - public const int MaxHttpMethodLength = 16; + /// + /// Default value: 16 + /// + public static int MaxHttpMethodLength { get; set; } = 16; - public const int MaxUserNameLength = 256; + /// + /// Default value: 256 + /// + public static int MaxUserNameLength { get; set; } = 256; - public const int MaxTenantNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxTenantNameLength { get; set; } = 64; } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs index d19407cfa4..b7f88db3e2 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs @@ -2,8 +2,14 @@ { public class EntityChangeConsts { - public const int MaxEntityTypeFullNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxEntityTypeFullNameLength { get; set; } = 128; - public const int MaxEntityIdLength = 128; + /// + /// Default value: 128 + /// + public static int MaxEntityIdLength { get; set; } = 128; } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs index 2ac9204395..8d592e06aa 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs @@ -2,12 +2,24 @@ { public class EntityPropertyChangeConsts { - public const int MaxNewValueLength = 512; + /// + /// Default value: 512 + /// + public static int MaxNewValueLength { get; set; } = 512; - public const int MaxOriginalValueLength = 512; + /// + /// Default value: 512 + /// + public static int MaxOriginalValueLength { get; set; } = 512; - public const int MaxPropertyNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxPropertyNameLength { get; set; } = 128; - public const int MaxPropertyTypeFullNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxPropertyTypeFullNameLength { get; set; } = 64; } } diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo/Abp/BackgroundJobs/BackgroundJobRecordConsts.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo/Abp/BackgroundJobs/BackgroundJobRecordConsts.cs index f4418bc423..01f935b30e 100644 --- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo/Abp/BackgroundJobs/BackgroundJobRecordConsts.cs +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain.Shared/Volo/Abp/BackgroundJobs/BackgroundJobRecordConsts.cs @@ -2,8 +2,14 @@ { public static class BackgroundJobRecordConsts { - public const int MaxJobNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxJobNameLength { get; set; } = 128; - public const int MaxJobArgsLength = 1024 * 1024; + /// + /// Default value: 1024 * 1024 + /// + public static int MaxJobArgsLength { get; set; } = 1024 * 1024; } } diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/DatabaseContainerConsts.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/DatabaseContainerConsts.cs index 0a71451f9f..22d127a1f1 100644 --- a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/DatabaseContainerConsts.cs +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/DatabaseContainerConsts.cs @@ -2,6 +2,9 @@ { public static class DatabaseContainerConsts { - public const int MaxNameLength = 128; + /// + /// Default value: 128. + /// + public static int MaxNameLength { get; set; } = 128; } } \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Create.cshtml.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Create.cshtml.cs index b2d89fbd55..6f4bae5e63 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Create.cshtml.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Create.cshtml.cs @@ -2,6 +2,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; using Volo.Blogging.Admin.Blogs; using Volo.Blogging.Blogs; @@ -44,14 +45,14 @@ namespace Volo.Blogging.Admin.Pages.Blogging.Admin.Blogs public class BlogCreateModalView { [Required] - [StringLength(BlogConsts.MaxNameLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] public string Name { get; set; } [Required] - [StringLength(BlogConsts.MaxShortNameLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxShortNameLength))] public string ShortName { get; set; } - [StringLength(BlogConsts.MaxDescriptionLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxDescriptionLength))] public string Description { get; set; } } diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Edit.cshtml.cs b/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Edit.cshtml.cs index 536810e015..8d0b2ba978 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Edit.cshtml.cs +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/Pages/Blogging/Admin/Blogs/Edit.cshtml.cs @@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; using Volo.Blogging.Admin.Blogs; using Volo.Blogging.Blogs; @@ -58,14 +59,14 @@ namespace Volo.Blogging.Admin.Pages.Blogging.Admin.Blogs public Guid Id { get; set; } [Required] - [StringLength(BlogConsts.MaxNameLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] public string Name { get; set; } [Required] - [StringLength(BlogConsts.MaxShortNameLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxShortNameLength))] public string ShortName { get; set; } - [StringLength(BlogConsts.MaxDescriptionLength)] + [DynamicStringLength(typeof(BlogConsts), nameof(BlogConsts.MaxDescriptionLength))] public string Description { get; set; } } } diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/BloggingWebConsts.cs b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/BloggingWebConsts.cs index ae4eb32dff..d9eb284ac6 100644 --- a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/BloggingWebConsts.cs +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/BloggingWebConsts.cs @@ -6,7 +6,10 @@ namespace Volo.Blogging { public class FileUploading { - public const int MaxFileSize = 5242880; //5MB + /// + /// Default value: 5242880 + /// + public static int MaxFileSize { get; set; } = 5242880; //5MB public static int MaxFileSizeAsMegabytes => Convert.ToInt32((MaxFileSize / 1024f) / 1024f); } diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/CreatePostDto.cs b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/CreatePostDto.cs index 164e4f691f..96cfbd6859 100644 --- a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/CreatePostDto.cs +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Posts/CreatePostDto.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; namespace Volo.Blogging.Posts { @@ -8,22 +9,22 @@ namespace Volo.Blogging.Posts public Guid BlogId { get; set; } [Required] - [StringLength(PostConsts.MaxTitleLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxTitleLength))] public string Title { get; set; } [Required] public string CoverImage { get; set; } [Required] - [StringLength(PostConsts.MaxUrlLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxUrlLength))] public string Url { get; set; } - [StringLength(PostConsts.MaxContentLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxContentLength))] public string Content { get; set; } public string Tags { get; set; } - [StringLength(PostConsts.MaxDescriptionLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxDescriptionLength))] public string Description { get; set; } } diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Blogs/BlogConsts.cs b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Blogs/BlogConsts.cs index 502a4364e7..b4b428207c 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Blogs/BlogConsts.cs +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Blogs/BlogConsts.cs @@ -2,10 +2,19 @@ { public static class BlogConsts { - public const int MaxNameLength = 256; + /// + /// Default value: 256 + /// + public static int MaxNameLength { get; set; } = 256; - public const int MaxShortNameLength = 32; + /// + /// Default value: 32 + /// + public static int MaxShortNameLength { get; set; } = 32; - public const int MaxDescriptionLength = 1024; + /// + /// Default value: 1024 + /// + public static int MaxDescriptionLength { get; set; } = 1024; } } diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Comments/CommentConsts.cs b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Comments/CommentConsts.cs index 34cc655fb3..359b322cbf 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Comments/CommentConsts.cs +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Comments/CommentConsts.cs @@ -2,6 +2,9 @@ { public class CommentConsts { - public const int MaxTextLength = 1024; + /// + /// Default value: 1024 + /// + public static int MaxTextLength { get; set; } = 1024; } } diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Posts/PostConsts.cs b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Posts/PostConsts.cs index 665984dfbb..de91caa2d3 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Posts/PostConsts.cs +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Posts/PostConsts.cs @@ -2,16 +2,34 @@ { public static class PostConsts { - public const int MaxTitleLength = 512; + /// + /// Default value: 512 + /// + public static int MaxTitleLength { get; set; } = 512; - public const int MaxUrlLength = 64; + /// + /// Default value: 64 + /// + public static int MaxUrlLength { get; set; } = 64; - public const int MaxContentLength = 1024 * 1024; //1MB + /// + /// Default value: 1024 * 1024 + /// + public static int MaxContentLength { get; set; } = 1024 * 1024; //1MB - public const int MaxDescriptionLength = 1000; + /// + /// Default value: 1000 + /// + public static int MaxDescriptionLength { get; set; } = 1000; - public const int MaxTitleLengthToBeSeoFriendly = 60; + /// + /// Default value: 60 + /// + public static int MaxTitleLengthToBeSeoFriendly { get; set; } = 60; - public const int MaxSeoFriendlyDescriptionLength = 200; + /// + /// Default value: 200 + /// + public static int MaxSeoFriendlyDescriptionLength { get; set; } = 200; } } diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Tagging/TagConsts.cs b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Tagging/TagConsts.cs index c75ccd4184..ad2be87ca8 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Tagging/TagConsts.cs +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Tagging/TagConsts.cs @@ -2,8 +2,14 @@ { public class TagConsts { - public const int MaxNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxNameLength { get; set; } = 64; - public const int MaxDescriptionLength = 512; + /// + /// Default value: 512 + /// + public static int MaxDescriptionLength { get; set; } = 512; } } diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs index c2ebcc441b..6d998a7172 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Validation; using Volo.Blogging.Blogs; using Volo.Blogging.Pages.Blogs.Shared.Helpers; using Volo.Blogging.Posts; @@ -85,7 +86,7 @@ namespace Volo.Blogging.Pages.Blog.Posts public Guid BlogId { get; set; } [Required] - [StringLength(PostConsts.MaxTitleLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxTitleLength))] public string Title { get; set; } [Required] @@ -93,14 +94,14 @@ namespace Volo.Blogging.Pages.Blog.Posts public string CoverImage { get; set; } [Required] - [StringLength(PostConsts.MaxUrlLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxUrlLength))] public string Url { get; set; } [HiddenInput] - [StringLength(PostConsts.MaxContentLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxContentLength))] public string Content { get; set; } - [StringLength(PostConsts.MaxDescriptionLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxDescriptionLength))] public string Description { get; set; } public string Tags { get; set; } diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs index 41c8f43ddd..3930a79900 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Validation; using Volo.Blogging.Blogs; using Volo.Blogging.Blogs.Dtos; using Volo.Blogging.Pages.Blogs.Shared.Helpers; @@ -79,7 +80,7 @@ namespace Volo.Blogging.Pages.Blog.Posts public Guid BlogId { get; set; } [Required] - [StringLength(PostConsts.MaxTitleLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxTitleLength))] public string Title { get; set; } [Required] @@ -87,16 +88,16 @@ namespace Volo.Blogging.Pages.Blog.Posts public string CoverImage { get; set; } [Required] - [StringLength(PostConsts.MaxUrlLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxUrlLength))] public string Url { get; set; } [HiddenInput] - [StringLength(PostConsts.MaxContentLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxContentLength))] public string Content { get; set; } public string Tags { get; set; } - [StringLength(PostConsts.MaxDescriptionLength)] + [DynamicStringLength(typeof(PostConsts), nameof(PostConsts.MaxDescriptionLength))] public string Description { get; set; } } diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs index e375f6ba0b..1512c13da9 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; using Volo.Abp.Application.Dtos; +using Volo.Abp.Validation; using Volo.Docs.Documents; namespace Volo.Docs.Admin.Documents @@ -9,19 +10,19 @@ namespace Volo.Docs.Admin.Documents { public Guid? ProjectId { get; set; } - [StringLength(DocumentConsts.MaxNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxNameLength))] public string Name { get; set; } - [StringLength(DocumentConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxVersionNameLength))] public string Version { get; set; } - [StringLength(DocumentConsts.MaxLanguageCodeNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxLanguageCodeNameLength))] public string LanguageCode { get; set; } - [StringLength(DocumentConsts.MaxFileNameNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxFileNameNameLength))] public string FileName { get; set; } - [StringLength(DocumentConsts.MaxFormatNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxFormatNameLength))] public string Format { get; set; } public DateTime? CreationTimeMin { get; set; } diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs index d796c00e64..c375de8b67 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Documents; namespace Volo.Docs.Admin.Documents @@ -8,10 +9,10 @@ namespace Volo.Docs.Admin.Documents { public Guid ProjectId { get; set; } - [StringLength(DocumentConsts.MaxLanguageCodeNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxLanguageCodeNameLength))] public string LanguageCode { get; set; } - [StringLength(DocumentConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxVersionNameLength))] public string Version { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs index fcc9816b02..dce5de0420 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Documents; namespace Volo.Docs.Admin.Documents @@ -8,13 +9,13 @@ namespace Volo.Docs.Admin.Documents { public Guid ProjectId { get; set; } - [StringLength(DocumentConsts.MaxNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxNameLength))] public string Name { get; set; } - [StringLength(DocumentConsts.MaxLanguageCodeNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxLanguageCodeNameLength))] public string LanguageCode { get; set; } - [StringLength(DocumentConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxVersionNameLength))] public string Version { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs index e6de68a3b1..506b674ba5 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Create.cshtml.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Validation; using Volo.Docs.Admin.Projects; using Volo.Docs.Projects; @@ -70,11 +71,11 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects public abstract class CreateProjectViewModelBase { [Required] - [StringLength(ProjectConsts.MaxNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxNameLength))] public string Name { get; set; } [Required] - [StringLength(ProjectConsts.MaxShortNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxShortNameLength))] [InputInfoText("ShortNameInfoText")] public string ShortName { get; set; } @@ -82,21 +83,21 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects [SelectItems(nameof(FormatTypes))] public string Format { get; set; } - [StringLength(ProjectConsts.MaxDefaultDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxDefaultDocumentNameLength))] public string DefaultDocumentName { get; set; } = "Index"; - [StringLength(ProjectConsts.MaxNavigationDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxNavigationDocumentNameLength))] public string NavigationDocumentName { get; set; } = "docs-nav.json"; - [StringLength(ProjectConsts.MaxParametersDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxParametersDocumentNameLength))] public string ParametersDocumentName { get; set; } = "docs-params.json"; - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string MinimumVersion { get; set; } public string MainWebsiteUrl { get; set; } - [StringLength(ProjectConsts.MaxLatestVersionBranchNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxLatestVersionBranchNameLength))] public string LatestVersionBranchName { get; set; } [HiddenInput] diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs index 3b9aba5303..ef1762c460 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Edit.cshtml.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Validation; using Volo.Docs.Admin.Projects; using Volo.Docs.Projects; @@ -83,28 +84,28 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects public Guid Id { get; set; } [Required] - [StringLength(ProjectConsts.MaxNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxNameLength))] public string Name { get; set; } [Required] [SelectItems(nameof(FormatTypes))] public string Format { get; set; } - [StringLength(ProjectConsts.MaxDefaultDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxDefaultDocumentNameLength))] public string DefaultDocumentName { get; set; } - [StringLength(ProjectConsts.MaxNavigationDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxNavigationDocumentNameLength))] public string NavigationDocumentName { get; set; } - [StringLength(ProjectConsts.MaxParametersDocumentNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxParametersDocumentNameLength))] public string ParametersDocumentName { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string MinimumVersion { get; set; } public string MainWebsiteUrl { get; set; } - [StringLength(ProjectConsts.MaxLatestVersionBranchNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxLatestVersionBranchNameLength))] public string LatestVersionBranchName { get; set; } } diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Pull.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Pull.cshtml.cs index 195337a22e..5cbd094834 100644 --- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Pull.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/Pull.cshtml.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; using Volo.Docs.Admin.Documents; using Volo.Docs.Admin.Projects; using Volo.Docs.Documents; @@ -60,15 +61,15 @@ namespace Volo.Docs.Admin.Pages.Docs.Admin.Projects public bool All { get; set; } [Required] - [StringLength(DocumentConsts.MaxNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxNameLength))] public string Name { get; set; } [Required] - [StringLength(DocumentConsts.MaxLanguageCodeNameLength)] + [DynamicStringLength(typeof(DocumentConsts),nameof(DocumentConsts.MaxLanguageCodeNameLength))] public string LanguageCode { get; set; } [Required] - [StringLength(DocumentConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxVersionNameLength))] public string Version { get; set; } } } diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDefaultDocumentInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDefaultDocumentInput.cs index 3deeb83967..1cef038512 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDefaultDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDefaultDocumentInput.cs @@ -1,5 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Runtime.CompilerServices; +using Volo.Abp.Validation; using Volo.Docs.Language; using Volo.Docs.Projects; @@ -9,11 +11,11 @@ namespace Volo.Docs.Documents { public Guid ProjectId { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string Version { get; set; } [Required] - [StringLength(LanguageConsts.MaxLanguageCodeLength)] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] public string LanguageCode { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentInput.cs index 412f41b82e..3646f2ade0 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Language; using Volo.Docs.Projects; @@ -10,14 +11,14 @@ namespace Volo.Docs.Documents public Guid ProjectId { get; set; } [Required] - [StringLength(DocumentConsts.MaxNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxNameLength))] public string Name { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string Version { get; set; } [Required] - [StringLength(LanguageConsts.MaxLanguageCodeLength)] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] public string LanguageCode { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentResourceInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentResourceInput.cs index 6f759c47d8..52c1cf78af 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentResourceInput.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetDocumentResourceInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Language; using Volo.Docs.Projects; @@ -10,14 +11,14 @@ namespace Volo.Docs.Documents public Guid ProjectId { get; set; } [Required] - [StringLength(DocumentConsts.MaxNameLength)] + [DynamicStringLength(typeof(DocumentConsts), nameof(DocumentConsts.MaxNameLength))] public string Name { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string Version { get; set; } [Required] - [StringLength(LanguageConsts.MaxLanguageCodeLength)] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] public string LanguageCode { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetNavigationDocumentInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetNavigationDocumentInput.cs index 6866c8c633..ee4e3380ee 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetNavigationDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetNavigationDocumentInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Language; using Volo.Docs.Projects; @@ -9,11 +10,11 @@ namespace Volo.Docs.Documents { public Guid ProjectId { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string Version { get; set; } [Required] - [StringLength(LanguageConsts.MaxLanguageCodeLength)] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] public string LanguageCode { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs index 33bd25b394..1e277f36a3 100644 --- a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs +++ b/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/GetParametersDocumentInput.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; using Volo.Docs.Language; using Volo.Docs.Projects; @@ -9,11 +10,11 @@ namespace Volo.Docs.Documents { public Guid ProjectId { get; set; } - [StringLength(ProjectConsts.MaxVersionNameLength)] + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] public string Version { get; set; } [Required] - [StringLength(LanguageConsts.MaxLanguageCodeLength)] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] public string LanguageCode { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs index f629abd0a4..04e3de3fd5 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs @@ -2,14 +2,49 @@ { public static class DocumentConsts { - public const int MaxNameLength = 255; - public const int MaxVersionNameLength = 128; - public const int MaxLanguageCodeNameLength = 128; - public const int MaxFileNameNameLength = 128; - public const int MaxFormatNameLength = 128; - public const int MaxEditLinkLength = 2048; - public const int MaxRootUrlLength = 2048; - public const int MaxRawRootUrlLength = 2048; - public const int MaxLocalDirectoryLength = 512; + /// + /// Default value: 255 + /// + public static int MaxNameLength { get; set; } = 255; + + /// + /// Default value: 128 + /// + public static int MaxVersionNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxLanguageCodeNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxFileNameNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxFormatNameLength { get; set; } = 128; + + /// + /// Default value: 2048 + /// + public static int MaxEditLinkLength { get; set; } = 2048; + + /// + /// Default value: 2048 + /// + public static int MaxRootUrlLength { get; set; } = 2048; + + /// + /// Default value: 2048 + /// + public static int MaxRawRootUrlLength { get; set; } = 2048; + + /// + /// Default value: 512 + /// + public static int MaxLocalDirectoryLength { get; set; } = 512; } } diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Language/LanguageConsts.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Language/LanguageConsts.cs index 867cc2dd4e..cd449a37fd 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Language/LanguageConsts.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Language/LanguageConsts.cs @@ -3,6 +3,9 @@ namespace Volo.Docs.Language { public static class LanguageConsts { - public const int MaxLanguageCodeLength = 10; + /// + /// Default value: 10 + /// + public static int MaxLanguageCodeLength { get; set; } = 10; } } diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs index 927a1a4c59..3322fb7732 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Projects/ProjectConsts.cs @@ -2,12 +2,39 @@ { public static class ProjectConsts { - public const int MaxNameLength = 128; - public const int MaxShortNameLength = 32; - public const int MaxDefaultDocumentNameLength = 128; - public const int MaxNavigationDocumentNameLength = 128; - public const int MaxParametersDocumentNameLength = 128; - public const int MaxLatestVersionBranchNameLength = 128; - public const int MaxVersionNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxNameLength { get; set; } = 128; + + /// + /// Default value: 32 + /// + public static int MaxShortNameLength { get; set; } = 32; + + /// + /// Default value: 128 + /// + public static int MaxDefaultDocumentNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxNavigationDocumentNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxParametersDocumentNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxLatestVersionBranchNameLength { get; set; } = 128; + + /// + /// Default value: 128 + /// + public static int MaxVersionNameLength { get; set; } = 128; } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureValueConsts.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureValueConsts.cs index 0fd1a644fa..f44deca44a 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureValueConsts.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureValueConsts.cs @@ -2,12 +2,24 @@ { public static class FeatureValueConsts { - public const int MaxNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxNameLength { get; set;} = 128; - public const int MaxProviderNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxProviderNameLength { get; set;} = 64; - public const int MaxProviderKeyLength = 64; + /// + /// Default value: 64 + /// + public static int MaxProviderKeyLength { get; set;} = 64; - public const int MaxValueLength = 128; + /// + /// Default value: 128 + /// + public static int MaxValueLength { get; set;} = 128; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityClaimTypeConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityClaimTypeConsts.cs index 6e15cb0cfc..d13d3fba0e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityClaimTypeConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityClaimTypeConsts.cs @@ -2,10 +2,29 @@ { public class IdentityClaimTypeConsts { + /// + /// Default value: 256 + /// public static int MaxNameLength { get; set; } = 256; + + /// + /// Default value: 512 + /// public static int MaxRegexLength { get; set; } = 512; + + /// + /// Default value: 128 + /// public static int MaxRegexDescriptionLength { get; set; } = 128; + + /// + /// Default value: 256 + /// public static int MaxDescriptionLength { get; set; } = 256; + + /// + /// Default value: 256 + /// public static int MaxConcurrencyStampLength { get; set; } = 256; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleConsts.cs index 33e8e74977..dfed056854 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityRoleConsts.cs @@ -2,8 +2,19 @@ { public static class IdentityRoleConsts { + /// + /// Default value: 256 + /// public static int MaxNameLength { get; set; } = 256; + + /// + /// Default value: 256 + /// public static int MaxNormalizedNameLength { get; set; } = 256; + + /// + /// Default value: 256 + /// public static int MaxConcurrencyStampLength { get; set; } = 256; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserClaimConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserClaimConsts.cs index a850d6cff2..84ba493853 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserClaimConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserClaimConsts.cs @@ -2,8 +2,14 @@ { public static class IdentityUserClaimConsts { + /// + /// Default value: 256 + /// public static int MaxClaimTypeLength { get; set; } = 256; + /// + /// Default value: 1024 + /// public static int MaxClaimValueLength { get; set; } = 1024; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs index 7b1a90dacc..378f545dff 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserConsts.cs @@ -18,12 +18,24 @@ namespace Volo.Abp.Identity public static int MaxPhoneNumberLength { get; set; } = AbpUserConsts.MaxPhoneNumberLength; + /// + /// Default value: 128 + /// public static int MaxPasswordLength { get; set; } = 128; + /// + /// Default value: 256 + /// public static int MaxPasswordHashLength { get; set; } = 256; + /// + /// Default value: 256 + /// public static int MaxSecurityStampLength { get; set; } = 256; - + + /// + /// Default value: 256 + /// public static int MaxConcurrencyStampLength { get; set; } = 256; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserLoginConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserLoginConsts.cs index 3f95dfd634..8435221fd3 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserLoginConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserLoginConsts.cs @@ -2,8 +2,19 @@ { public static class IdentityUserLoginConsts { + /// + /// Default value: 64 + /// public static int MaxLoginProviderLength { get; set; } = 64; + + /// + /// Default value: 196 + /// public static int MaxProviderKeyLength { get; set; } = 196; + + /// + /// Default value: 128 + /// public static int MaxProviderDisplayNameLength { get; set; } = 128; } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserTokenConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserTokenConsts.cs index 1e4eb4794b..a585a8383b 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserTokenConsts.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserTokenConsts.cs @@ -2,8 +2,14 @@ { public static class IdentityUserTokenConsts { + /// + /// Default value: 64 + /// public static int MaxLoginProviderLength { get; set; } = 64; + /// + /// Default value: 128 + /// public static int MaxNameLength { get; set; } = 128; } } diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientIdPRestrictionConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientIdPRestrictionConsts.cs index c71301871a..b238a01935 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientIdPRestrictionConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientIdPRestrictionConsts.cs @@ -2,6 +2,9 @@ { public class ClientIdPRestrictionConsts { - public const int ProviderMaxLength = 200; + /// + /// Default value: 200 + /// + public static int ProviderMaxLength { get; set; } = 200; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUriConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUriConsts.cs index 3092232d47..7d4764e1a3 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUriConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUriConsts.cs @@ -2,7 +2,10 @@ { public class ClientPostLogoutRedirectUriConsts { - public const int PostLogoutRedirectUriMaxLength = 2000; + /// + /// Default value: 200 + /// + public static int PostLogoutRedirectUriMaxLength { get; set; } = 2000; public static int PostLogoutRedirectUriMaxLengthValue { get; set; } = 2000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPropertyConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPropertyConsts.cs index 6535304596..664e1076b0 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPropertyConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientPropertyConsts.cs @@ -2,7 +2,14 @@ { public class ClientPropertyConsts { - public const int KeyMaxLength = 250; - public const int ValueMaxLength = 2000; + /// + /// Default value: 250 + /// + public static int KeyMaxLength { get; set; } = 250; + + /// + /// Default value: 2000 + /// + public static int ValueMaxLength { get; set; } = 2000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientRedirectUriConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientRedirectUriConsts.cs index e972388487..7650a3d952 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientRedirectUriConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientRedirectUriConsts.cs @@ -2,7 +2,10 @@ { public class ClientRedirectUriConsts { - public const int RedirectUriMaxLength = 2000; + /// + /// Default value: 2000 + /// + public static int RedirectUriMaxLength { get; set; } = 2000; public static int RedirectUriMaxLengthValue { get; set; } = 2000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientScopeConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientScopeConsts.cs index 6a5b62e692..0ec1c04595 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientScopeConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Clients/ClientScopeConsts.cs @@ -2,6 +2,9 @@ { public class ClientScopeConsts { - public const int ScopeMaxLength = 200; + /// + /// Default value: 200 + /// + public static int ScopeMaxLength { get; set; } = 200; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Grants/PersistedGrantConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Grants/PersistedGrantConsts.cs index 6d0836ab17..b1dd21d6f8 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Grants/PersistedGrantConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Grants/PersistedGrantConsts.cs @@ -2,11 +2,34 @@ { public class PersistedGrantConsts { - public const int KeyMaxLength = 200; - public const int TypeMaxLength = 50; - public const int SubjectIdMaxLength = 200; - public const int ClientIdMaxLength = 200; - public const int DataMaxLength = 50000; - public static int DataMaxLengthValue { get; set; }= 50000; + /// + /// Default value: 200 + /// + public static int KeyMaxLength { get; set; } = 200; + + /// + /// Default value: 50 + /// + public static int TypeMaxLength { get; set; } = 50; + + /// + /// Default value: 200 + /// + public static int SubjectIdMaxLength { get; set; } = 200; + + /// + /// Default value: 200 + /// + public static int ClientIdMaxLength { get; set; } = 200; + + /// + /// Default value: 50000 + /// + public static int DataMaxLength { get; set; } = 50000; + + /// + /// Default value: 50000 + /// + public static int DataMaxLengthValue { get; set; } = 50000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceConsts.cs index c60cc34ad8..a7c713e161 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityResources/IdentityResourceConsts.cs @@ -2,8 +2,19 @@ { public class IdentityResourceConsts { - public const int NameMaxLength = 200; - public const int DisplayNameMaxLength = 200; - public const int DescriptionMaxLength = 1000; + /// + /// Default value: 200 + /// + public static int NameMaxLength { get; set; } = 200; + + /// + /// Default value: 200 + /// + public static int DisplayNameMaxLength { get; set; } = 200; + + /// + /// Default value: 200 + /// + public static int DescriptionMaxLength { get; set; } = 1000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/SecretConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/SecretConsts.cs index 76635e322e..156088a97b 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/SecretConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/SecretConsts.cs @@ -2,9 +2,21 @@ { public class SecretConsts { - public const int TypeMaxLength = 250; - public const int ValueMaxLength = 4000; + /// + /// Default value: 250 + /// + public static int TypeMaxLength { get; set; } = 250; + + /// + /// Default value: 4000 + /// + public static int ValueMaxLength { get; set; } = 4000; + public static int ValueMaxLengthValue { get; set; } = ValueMaxLength; - public const int DescriptionMaxLength = 2000; + + /// + /// Default value: 2000 + /// + public static int DescriptionMaxLength { get; set; } = 2000; } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/UserClaimConsts.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/UserClaimConsts.cs index 9133482f1f..cb0279fd2b 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/UserClaimConsts.cs +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/UserClaimConsts.cs @@ -2,6 +2,9 @@ { public class UserClaimConsts { - public const int TypeMaxLength = 200; + /// + /// Default value: 200 + /// + public static int TypeMaxLength { get; set; } = 200; } } \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs index 8d579638ec..5cb2397349 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs @@ -2,10 +2,19 @@ { public static class PermissionGrantConsts { - public const int MaxNameLength = 128; + /// + /// Default value: 128 + /// + public static int MaxNameLength { get; set; } = 128; - public const int MaxProviderNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxProviderNameLength { get; set; } = 64; - public const int MaxProviderKeyLength = 64; + /// + /// Default value: 64 + /// + public static int MaxProviderKeyLength { get; set; } = 64; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingConsts.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingConsts.cs index 44a21f3ccb..e23a0e39a5 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingConsts.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingConsts.cs @@ -2,10 +2,26 @@ { public static class SettingConsts { - public const int MaxNameLength = 128; - public const int MaxValueLength = 2048; + /// + /// Default value: 128 + /// + public static int MaxNameLength { get; set; } = 128; + + /// + /// Default value: 2048 + /// + public static int MaxValueLength { get; set; } = 2048; + public static int MaxValueLengthValue { get; set; } = MaxValueLength; - public const int MaxProviderNameLength = 64; - public const int MaxProviderKeyLength = 64; + + /// + /// Default value: 64 + /// + public static int MaxProviderNameLength { get; set; } = 64; + + /// + /// Default value: 64 + /// + public static int MaxProviderKeyLength { get; set; } = 64; } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantCreateOrUpdateDtoBase.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantCreateOrUpdateDtoBase.cs index 19f73b0d51..7dc805ea79 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantCreateOrUpdateDtoBase.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/TenantCreateOrUpdateDtoBase.cs @@ -1,12 +1,13 @@ using System.ComponentModel.DataAnnotations; using Volo.Abp.ObjectExtending; +using Volo.Abp.Validation; namespace Volo.Abp.TenantManagement { public abstract class TenantCreateOrUpdateDtoBase : ExtensibleObject { [Required] - [StringLength(TenantConsts.MaxNameLength)] + [DynamicStringLength(typeof(TenantConsts), nameof(TenantConsts.MaxNameLength))] public string Name { get; set; } } } \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConnectionStringConsts.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConnectionStringConsts.cs index 4cdf8dee2a..b177e8d046 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConnectionStringConsts.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConnectionStringConsts.cs @@ -2,8 +2,14 @@ { public static class TenantConnectionStringConsts { - public const int MaxNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxNameLength { get; set; } = 64; - public const int MaxValueLength = 1024; + /// + /// Default value: 1024 + /// + public static int MaxValueLength { get; set; } = 1024; } } \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConsts.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConsts.cs index 328c422ab9..10de5e8773 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConsts.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/TenantConsts.cs @@ -2,6 +2,9 @@ { public static class TenantConsts { - public const int MaxNameLength = 64; + /// + /// Default value: 64 + /// + public static int MaxNameLength { get; set; } = 64; } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs index 9093437f98..45a36060e0 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/ConnectionStringsModal.cshtml.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants { @@ -53,7 +54,7 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants public bool UseSharedDatabase { get; set; } - [StringLength(TenantConnectionStringConsts.MaxValueLength)] + [DynamicStringLength(typeof(TenantConnectionStringConsts), nameof(TenantConnectionStringConsts.MaxValueLength))] public string DefaultConnectionString { get; set; } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs index fa517594ee..0c1e6e0bec 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/CreateModal.cshtml.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants { @@ -34,7 +35,7 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants public class TenantInfoModel { [Required] - [StringLength(TenantConsts.MaxNameLength)] + [DynamicStringLength(typeof(TenantConsts), nameof(TenantConsts.MaxNameLength))] public string Name { get; set; } [Required] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs index 74ac176b02..736d0174cf 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/EditModal.cshtml.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Validation; namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants { @@ -42,7 +43,7 @@ namespace Volo.Abp.TenantManagement.Web.Pages.TenantManagement.Tenants public Guid Id { get; set; } [Required] - [StringLength(TenantConsts.MaxNameLength)] + [DynamicStringLength(typeof(TenantConsts), nameof(TenantConsts.MaxNameLength))] [Display(Name = "DisplayName:TenantName")] public string Name { get; set; } } diff --git a/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs b/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs index ee37c6c9f4..efbd2e02b2 100644 --- a/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs +++ b/modules/users/src/Volo.Abp.Users.Domain.Shared/Volo/Abp/Users/AbpUserConsts.cs @@ -2,14 +2,29 @@ namespace Volo.Abp.Users { public class AbpUserConsts { + /// + /// Default value: 256 + /// public static int MaxUserNameLength { get; set; } = 256; + /// + /// Default value: 64 + /// public static int MaxNameLength { get; set; } = 64; + /// + /// Default value: 64 + /// public static int MaxSurnameLength { get; set; } = 64; + /// + /// Default value: 256 + /// public static int MaxEmailLength { get; set; } = 256; + /// + /// Default value: 16 + /// public static int MaxPhoneNumberLength { get; set; } = 16; } } \ No newline at end of file diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts index dfe290d12f..2199411a1c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts @@ -11,6 +11,10 @@ import { ViewEncapsulation, } from '@angular/core'; +/** + * + * @deprecated use ngx-datatale instead. + */ @Component({ selector: 'abp-table', templateUrl: 'table.component.html', diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj index f0b3cc8b33..df627353c0 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj @@ -5,8 +5,9 @@ netstandard2.0 MyCompanyName.MyProjectName + true - + @@ -23,4 +24,8 @@ + + + + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs index 340d28ac3a..7fb1e30637 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs @@ -35,7 +35,7 @@ namespace MyCompanyName.MyProjectName { Configure(options => { - options.FileSets.AddEmbedded("MyCompanyName.MyProjectName"); + options.FileSets.AddEmbedded(); }); Configure(options => diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index caa21c9706..1da9619803 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -77,8 +77,6 @@ namespace MyCompanyName.MyProjectName { Configure(options => { - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Domain.Shared")); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Domain")); // options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -87,6 +85,8 @@ namespace MyCompanyName.MyProjectName options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}modules{0}account{0}src{0}Volo.Abp.Account.Web", Path.DirectorySeparatorChar))); // + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Domain.Shared")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Domain")); }); } diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/tr.json b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/tr.json index 2b48193353..8decb5134e 100644 --- a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/tr.json +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/tr.json @@ -1,6 +1,6 @@ { "culture": "tr", "texts": { - "ManageYourProfile": "Profil yönetimi" + "ManageYourProfile": "Profil yönetimi" } } \ No newline at end of file diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj index 3483fb41cd..526c13a2e4 100644 --- a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyCompanyName.MyProjectName.Domain.Shared.csproj @@ -5,12 +5,17 @@ netstandard2.0 MyCompanyName.MyProjectName + true + + + + diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs index 384aae162a..081ccfb739 100644 --- a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/MyProjectNameDomainSharedModule.cs @@ -17,7 +17,7 @@ namespace MyCompanyName.MyProjectName { Configure(options => { - options.FileSets.AddEmbedded("MyCompanyName.MyProjectName"); + options.FileSets.AddEmbedded(); }); Configure(options =>