What we really miss in the entities generated by the ABP Suite is a GetList-Method that returns the data without pagination. By customizing certain templates, we have now added these missing methods ourselves.
Here are some examples of our customizations:
Server.Controller.ItemController.txt:
[HttpGet]
public virtual Task<List<%%entity-name%%Dto>> GetListAsync(Get%%entity-name-plural%%Input input)
{
return _%%entity-name-plural-camelcase%%AppService.GetListAsync(input);
}
[HttpGet]
[Route("paged")]
public virtual Task<PagedResultDto<%%entity-name%%Dto>> GetPagedListAsync(Get%%entity-name-plural%%Input input)
{
return _%%entity-name-plural-camelcase%%AppService.GetPagedListAsync(input);
}
Server.AppService.AppService.txt:
public virtual async Task<List<%%entity-name%%Dto>> GetListAsync(Get%%entity-name-plural%%Input input)
{
var items = await _%%entity-name-camelcase%%Repository.GetListAsync(input.FilterText, %%input-properties%%%%<if:HasFilterableProperties>%%, %%</if:HasFilterableProperties>%%input.Sorting);
return ObjectMapper.Map<List<%%entity-name%%>, List<%%entity-name%%Dto>>(items);
}
public virtual async Task<PagedResultDto<%%entity-name%%Dto>> GetPagedListAsync(Get%%entity-name-plural%%Input input)
{
var totalCount = await _%%entity-name-camelcase%%Repository.GetCountAsync(input.FilterText%%<if:HasFilterableProperties>%%, %%</if:HasFilterableProperties>%%%%input-properties%%);
var items = await _%%entity-name-camelcase%%Repository.GetListAsync(input.FilterText, %%input-properties%%%%<if:HasFilterableProperties>%%, %%</if:HasFilterableProperties>%%input.Sorting, input.MaxResultCount, input.SkipCount);
return new PagedResultDto<%%entity-name%%Dto>
{
TotalCount = totalCount,
Items = ObjectMapper.Map<List<%%entity-name%%>, List<%%entity-name%%Dto>>(items)
};
}
Here's my problem / my question:
For my GetListAsync method, I used the same input class that’s also used for the paged list. The problem, however, is that Angular requires a value to be set for MaxResultCount, even if that value isn’t used. This is poor design and confuses developers.
How could I use the ABP Suite to generate a custom input class for this? Ideally, of course, I’d be able to create a Server.AppService.GetItemsPagedInput.txt file in addition to the Server.AppService.GetItemsInput.txt template.
Is it possible to create your own templates? If so, where would they be saved?
Thanks, Adrian
Environment:
- Template: app
- Template Type: Classic
- Created ABP Studio Version: 2.2.1
- Current ABP Studio Version: 3.0.6
- Tiered: No
- Multi-Tenancy: Yes
- UI Framework: angular
- Theme: leptonx
- Theme Style: system
- Theme Menu Placement: side
- Progressive Web App: No
- Run Progressive Web App Support: No
- Database Provider: ef
- Database Management System: sqlserver
- Separate Tenant Schema: Yes
- Mobile Framework: none
- Public Website: No
- Social Login: Yes
- Include Tests: Yes
- Kubernetes Configuration: Yes
- Distributed Event Bus: none
- Use Local References: No
- Optional Modules:
- GDPR
- FileManagement
- TextTemplateManagement
- LanguageManagement
- AuditLogging
- OpenIddictAdmin
- Selected Languages: German (Switzerland), English, French, German (Germany), Italian
- Default Language: German (Switzerland)
- Create Command: abp new Bpo -t app --ui-framework angular --database-provider ef --database-management-system sqlserver --theme leptonx --separate-tenant-schema --skip-migration --skip-migrator --without-cms-kit --dont-run-install-libs --dont-run-bundling -file-management
8 Answer(s)
-
0
- ABP Suite doesn’t support adding brand-new template files (like an additional
Server.AppService.GetItemsPagedInput.txt) that participate in generation. It generates based on the built-in template set that matches your ABP version; you can only customize/override existing templates. - ABP Suite doesn’t store templates in a user folder; the templates it uses are located in your solution (this is why Suite version and your ABP version must match).
So, for your specific need (a non-paged
GetListAsyncinput withoutMaxResultCount/SkipCount):- Keep your extra non-paged method, but don’t reuse
PagedAndSortedResultRequestDto-based input. - Create a separate DTO manually (or via your own post-generation process), e.g.:
using Volo.Abp.Application.Dtos; public class GetItemsInput : SortedResultRequestDto { public string? FilterText { get; set; } // your filterable properties... }and keep the paged one as:
public class GetItemsPagedInput : PagedAndSortedResultRequestDto { public string? FilterText { get; set; } // your filterable properties... }- In Angular, point the non-paged call to the non-paged input type so
maxResultCountisn’t required/expected by the generated TS typings.
Links worth noting (verified):
- https://abp.io/support/questions/671 (explains templates are located in the solution; Suite version must match ABP version)
- https://abp.io/support/questions/65 (template customization/outdated template behavior in Suite)
- https://abp.io/docs/latest/studio/working-with-suite
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - ABP Suite doesn’t support adding brand-new template files (like an additional
-
0
A somewhat clunky but probably functional workaround might be to define a second input class in GetItemsInput.txt. However, I would prefer other solutions.
Server.AppService.GetItemsInput.txt:
using Volo.Abp.Application.Dtos; using System; namespace %%solution-namespace%%%%<if:ApplicationContractsNotExists>%%%%.AppServices%%</if:ApplicationContractsNotExists>%%.%%microservice-dtos-namespace-prefix%%%%entity-namespace%% { public %%custom-code-abstract-modifier%% class Get%%entity-name-plural%%PagedInput%%custom-code-base%% : PagedAndSortedResultRequestDto { public string? FilterText { get; set; } %%property-definitions%% public Get%%entity-name-plural%%PagedInput%%custom-code-base%%() { } } public %%custom-code-abstract-modifier%% class Get%%entity-name-plural%%Input%%custom-code-base%% { public string? FilterText { get; set; } %%property-definitions%% public Get%%entity-name-plural%%Input%%custom-code-base%%() { } } }Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Suite can only override the templates it already knows about. During generation it reads a fixed set of built-in template names and matches your overrides to them by file name, so a brand-new file like
Server.AppService.GetItemsPagedInput.txtis never requested and just gets ignored. So adding a separate template file isn't possible, you can only override the existing ones (which you're already doing, in your solution's customized templates folder).You don't need a separate file for this, though. You can define the extra input class right inside your
Server.AppService.GetItemsInput.txtoverride, and%%property-definitions%%is filled for every class in the file, so both inputs keep their filterable properties in sync automatically.I'd leave the default
Get...Input(paged) exactly as the built-in template generates it, which keeps the default paged list and its Angular grid untouched, and just add a second non-paged class next to it:using Volo.Abp.Application.Dtos; using System; namespace %%solution-namespace%%%%<if:ApplicationContractsNotExists>%%%%.AppServices%%</if:ApplicationContractsNotExists>%%.%%microservice-dtos-namespace-prefix%%%%entity-namespace%% { public %%custom-code-abstract-modifier%% class Get%%entity-name-plural%%Input%%custom-code-base%% : PagedAndSortedResultRequestDto { public string? FilterText { get; set; } %%property-definitions%% public Get%%entity-name-plural%%Input%%custom-code-base%%() { } } public class Get%%entity-name-plural%%ListInput : ISortedResultRequest { public string? FilterText { get; set; } public string? Sorting { get; set; } %%property-definitions%% } }Then change your non-paged app service method (and the matching controller action) to take
Get<Entities>ListInput, and leave the paged method onGet<Entities>Input. Since the non-paged input has noMaxResultCount/SkipCount, they won't show up in the generated Angular model anymore, so the requiredmaxResultCountgoes away.Two details to watch:
- The non-paged class needs that
Sortingproperty, since yourGetListAsyncpassesinput.Sortingto the repository. ImplementingISortedResultRequest(as above) is the cleanest way to get it without the paging fields. - Keep the second class plain (no
%%custom-code-abstract-modifier%%/%%custom-code-base%%). Those turn the default input into an abstract...Baseclass with a generated.Extendedpartial inheriting it, and that partial is only created for the default input name. Put them on the new class and you'd get an abstract type with nothing inheriting from it.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) - The non-paged class needs that
-
0
Thanks for the feedback. I've now successfully implemented it using a
...PagedListInput(the existing class) and...ListInput(the new class withISortedResultRequest). And I wanted to do it “correctly” from the start using the extended partial class, so I've also adapted that template.Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
A while back, I posted two feature requests under “ABP Suite feature requests”. Do you know if they were noted and, if so, whether they'll be implemented at some point?
https://abp.io/support/questions/8803/ABP-Suite-feature-request--2025#answer-3a20f067-49ef-b56a-6a66-0d1671aa7bf2
https://abp.io/support/questions/8803/ABP-Suite-feature-request--2025#answer-3a20f070-f3b8-a78e-2794-b2edbaa436b7
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Glad it's working now, and nice that you also wired it through the extended partial class, that's the cleaner way to keep it regeneration-safe.
About the two requests from the Suite feature-requests thread: both are noted on our side and we do plan to implement them.
- Not forcing a string display property on a navigation property: we'll allow picking a non-string property and leave that choice to the developer.
- Choosing the output folder for a generated entity: we'll add support for this as well.
I can't tie either to a specific release yet, but they're planned and not forgotten.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)