Tooark.Dtos 4.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Tooark.Dtos --version 4.0.1
                    
NuGet\Install-Package Tooark.Dtos -Version 4.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tooark.Dtos" Version="4.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tooark.Dtos" Version="4.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Tooark.Dtos" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tooark.Dtos --version 4.0.1
                    
#r "nuget: Tooark.Dtos, 4.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tooark.Dtos@4.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tooark.Dtos&version=4.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Tooark.Dtos&version=4.0.1
                    
Install as a Cake Tool

Tooark.Dtos

Biblioteca para gerenciamento e manutenção de DTOs base em projetos .NET.

Conteúdo

Visão Geral

O pacote Tooark.Dtos fornece:

  • DTOs de busca e paginação para endpoints de listagem;
  • uma resposta padrão com dados, erros, paginação e metadados;
  • tradução automática das chaves de erro produzidas pelas validações do Tooark;
  • limite de tamanho de página, para que uma requisição não possa pedir todos os registros.

Requisito de runtime: SearchDto, PaginationDto e ResponseDto usam tipos do MVC, do Http e do WebUtilities, então o pacote exige o runtime do ASP.NET Core instalado. É o esperado para DTOs de API.


🔧 Instalação

dotnet add package Tooark.Dtos

⚙️ Configuração

A tradução das mensagens não exige configuração: o ResponseDto resolve o idioma pelo fluxo de execução da requisição e lê as traduções dos arquivos distribuídos com o Tooark.Extensions.

O registro abaixo existe para a aplicação poder injetar IStringLocalizer nos próprios tipos:

using Tooark.Dtos.Injections;

builder.Services.AddTooarkDtos();

Para acrescentar ou sobrescrever traduções, coloque um Resources/{idioma}.json na saída da aplicação.


📦 Componentes

Dto

Classe base dos DTOs que produzem mensagens traduzidas. Não tem membros públicos: serve para o ResponseDto e o SearchDto compartilharem o localizador.

SearchDto

Parâmetros de busca com paginação.

Membro Tipo Descrição
Search string? Informação a ser procurada. Padrão: nulo
SearchNormalized string? Search normalizado, calculado uma vez por valor. Não é vinculado nem serializado
PageIndex long Índice da página, começando em 1. Valor menor assume 1. Padrão: 1
PageIndexLogical long PageIndex menos um, para uso direto em Skip. Não é vinculado nem serializado
PageSize long Tamanho da página. Negativo assume 0, que significa ignorar o tamanho. Padrão: 10
PageSizeMax long protected virtual. Teto do PageSize. Padrão: DefaultPageSizeMax
DefaultPageSizeMax const long Teto padrão: 100

SearchOrderDto

Herda de SearchDto e acrescenta ordenação.

Membro Tipo Descrição
OrderBy string? Nome da coluna a ordenar
OrderAsc bool Crescente quando verdadeiro. Padrão: true

PaginationDto

Total de registros e navegação entre páginas. Todas as propriedades são somente leitura.

Membro Tipo Descrição
Total long Total de registros
PageSize / PageIndex long Tamanho e índice da página
Previous / Next long? Índices das páginas vizinhas, nulos quando não existem
CurrentLink / PreviousLink / NextLink string? URLs correspondentes

ResponseDto<T>

Resposta padrão de API.

Membro Tipo Descrição
Data T? Dados da resposta
Errors IReadOnlyList<string> Mensagens de erro, já traduzidas
Pagination PaginationDto? Dados de paginação
Metadata IReadOnlyList<MetadataDto> Metadados
SetPagination / SetMetadata / AddMetadata Definem paginação e metadados após a construção

Errors e Metadata são coleções somente leitura: convertê-las para IList compila, mas alterá-las lança NotSupportedException. Use SetMetadata ou AddMetadata.

MetadataDto

Par chave/valor. Chave e valor são independentes — informar um como nulo resulta em string vazia, sem descartar o outro.

Limite de tamanho de página

Sem um teto, uma única requisição poderia pedir todos os registros. O PageSize é limitado a DefaultPageSizeMax, que vale 100. Um endpoint que precise de páginas maiores sobrescreve o limite no próprio DTO:

public sealed class RelatorioSearchDto : SearchDto
{
  protected override long PageSizeMax => 5000;
}

Use a forma de expressão. Uma propriedade automática com inicializador não serve: o limite é consultado pelo construtor da classe base, que roda antes dos inicializadores da classe derivada.

Os links reaproveitam a query string da requisição, trocando apenas o PageIndex, para que os filtros do endpoint sigam valendo na navegação.

Duas consequências que valem conhecer:

  • Todo parâmetro da requisição aparece no corpo da resposta. Não trafegue credenciais na query string — elas voltariam nos links e daí para logs, cache e histórico do navegador.
  • Os links não são um controle de acesso. Quem consegue chamar uma página consegue chamar as outras editando a URL, e o Total já informa quantas existem. Contra coleta em massa, o que vale é o teto de PageSize, o limite de taxa e a autorização — não esconder os links.

📝 Exemplos de Uso

Busca com paginação

using Microsoft.AspNetCore.Mvc;
using Tooark.Dtos;

[HttpGet]
public async Task<IActionResult> Listar([FromQuery] SearchDto filtro)
{
  var query = _context.Pessoas.AsQueryable();

  if (!string.IsNullOrEmpty(filtro.SearchNormalized))
  {
    query = query.Where(p => p.NomeNormalizado.Contains(filtro.SearchNormalized));
  }

  var total = await query.LongCountAsync();

  var pessoas = await query
    .Skip((int)(filtro.PageIndexLogical * filtro.PageSize))
    .Take((int)filtro.PageSize)
    .ToListAsync();

  var resposta = new ResponseDto<List<Pessoa>>(pessoas);
  resposta.SetPagination(new PaginationDto(total, filtro, Request));

  return Ok(resposta);
}

A resposta:

{
  "data": [ ... ],
  "errors": [],
  "pagination": {
    "total": 95,
    "pageSize": 10,
    "pageIndex": 9,
    "previous": 8,
    "next": 10,
    "currentLink": "https://api.exemplo.com/pessoas?PageIndex=9&PageSize=10",
    "previousLink": "https://api.exemplo.com/pessoas?PageIndex=8&PageSize=10",
    "nextLink": "https://api.exemplo.com/pessoas?PageIndex=10&PageSize=10"
  },
  "metadata": []
}

Não chame o parâmetro de search. O SearchDto tem uma propriedade Search, e o ASP.NET Core emite o aviso MVC1004 quando o nome do parâmetro coincide com o de uma propriedade do tipo vinculado, porque a resolução de prefixo fica ambígua. Qualquer outro nome resolve.

Busca com ordenação

using Tooark.Dtos;

[HttpGet]
public IActionResult Listar([FromQuery] SearchOrderDto filtro)
{
  var query = _context.Pessoas.OrderByProperty(filtro.OrderBy ?? nameof(Pessoa.Nome));

  // ...
}

Resposta com erros de validação

using Tooark.Dtos;

var pessoa = new Pessoa(nome, email);

// A notificação inválida vira a lista de erros, já traduzida
if (!pessoa.IsValid)
{
  // ["O campo Nome é obrigatório"]
  return BadRequest(new ResponseDto<Pessoa>(pessoa));
}

Com o código do erro na frente da mensagem:

// ["T.VLD.STR5: O campo Nome é obrigatório"]
return BadRequest(new ResponseDto<Pessoa>(pessoa.Notification, withCode: true));

Endpoint com página maior

using Tooark.Dtos;

public sealed class ExportacaoSearchDto : SearchDto
{
  protected override long PageSizeMax => 5000;
}

[HttpGet("exportacao")]
public IActionResult Exportar([FromQuery] ExportacaoSearchDto filtro)
{
  // filtro.PageSize aceita até 5000 neste endpoint
}

Metadados

using Tooark.Dtos;

var resposta = new ResponseDto<List<Pessoa>>(pessoas);

resposta.AddMetadata(new MetadataDto("versao", "2024-01"));
resposta.SetMetadata([new MetadataDto("origem", "cache")]);

📋 Dependências

Pacote Versão Descrição
Tooark.Extensions 4.x Localização das mensagens e normalização da busca
Tooark.Notifications 4.x Notificações que viram os erros da resposta
Microsoft.AspNetCore.App (framework compartilhado) 8.x/10.x HttpRequest, QueryHelpers e BindNever

🪪 Contribuição

Contribuições são bem-vindas! Sinta-se à vontade para abrir issues e pull requests no repositório Tooark.Dtos.

📄 Licença

Este projeto está licenciado sob a licença BSD 3-Clause. Veja o arquivo LICENSE para mais detalhes.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Tooark.Dtos:

Package Downloads
Tooark

Package with all Tooark resources for .NET applications.

Tooark.AspNetCore

Package with the ASP.NET Core specific pieces of Tooark for .NET applications.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.7.1 0 10/17/2026
4.7.0 146 9/30/2026
4.6.0 156 9/29/2026
4.5.0 110 9/29/2026
4.4.0 104 9/28/2026
4.3.0 115 9/26/2026
4.2.1 112 9/25/2026
4.2.0 126 9/20/2026
4.1.0 116 9/18/2026
4.0.1 203 8/25/2026
4.0.0 128 8/25/2026
3.3.6 106 9/18/2026
3.3.5 119 8/25/2026
3.3.4 138 8/12/2026
3.3.3 138 7/27/2026
3.3.2 291 6/11/2026
3.3.1 155 6/6/2026
2.3.5 99 9/18/2026
2.3.4 117 8/25/2026
2.3.3 129 7/27/2026
Loading failed