Jarvis.Toolkit
1.2.2.6
See the version list below for details.
dotnet add package Jarvis.Toolkit --version 1.2.2.6
NuGet\Install-Package Jarvis.Toolkit -Version 1.2.2.6
<PackageReference Include="Jarvis.Toolkit" Version="1.2.2.6" />
<PackageVersion Include="Jarvis.Toolkit" Version="1.2.2.6" />
<PackageReference Include="Jarvis.Toolkit" />
paket add Jarvis.Toolkit --version 1.2.2.6
#r "nuget: Jarvis.Toolkit, 1.2.2.6"
#:package Jarvis.Toolkit@1.2.2.6
#addin nuget:?package=Jarvis.Toolkit&version=1.2.2.6
#tool nuget:?package=Jarvis.Toolkit&version=1.2.2.6
Jarvis.Toolkit
Biblioteca de utilidades para .NET com extensões, validações, serviços HTTP, criptografia, autenticação, e-mail, notificações push e muito mais.
Instalação
dotnet add package Jarvis.Toolkit
Extensões
String
// Extrair conteúdo
"123.456.789-00".GetOnlyNumbers(); // "12345678900"
"-12a3".GetOnlyNumbers(allowSign: true); // "-123" (mantém '-' só na 1ª posição)
"abc123".GetOnlyLetters(); // "abc"
"user@mail.com".GetSubstringBeforeChar('@'); // "user"
"abcdef".Take(3); // "abc"
"abcdef".TakeLast(3); // "def"
// Verificações
"texto".IsNullOrEmpty(); // false
" ".IsNullOrEmptyOrWhiteSpace(); // true
"".NotNullOrEmpty(); // false
"texto".NotNullOrEmptyOrWhiteSpace(); // true
// Caixa e capitalização
" ABC ".TrimToLower(); // "abc"
" abc ".TrimToUpper(); // "ABC"
"hello world".FirstCharToUpper(); // "Hello world"
"hELLO WORLD".OnlyFirstCharToUpper(); // "Hello world"
"hello world".AllFirstCharToUpper(); // "Hello World"
// Máscara
"12345678900".SetMask(MaskType.CPF); // "123.456.789-00"
"12345678000199".SetMask(MaskType.CNPJ); // "12.345.678/0001-99"
"12345678".SetMask(MaskType.CEP); // "12345-678"
"1134567890".SetMask(MaskType.Telephone); // "(11) 3456-7890"
"11987654321".SetMask(MaskType.Cellphone); // "(11) 98765-4321"
"11987654321".SetMask(MaskType.PhoneNumber); // "(11) 98765-4321" (10 dígitos = fixo)
"123456".SetMask(MaskType.Money); // "R$ 1.234,56"
"1250".SetMask(MaskType.Percent); // "12,50%"
"1234".SetMask(MaskType.Numeric); // "1.234"
"1430".SetMask(MaskType.Time); // "14:30"
"143000".SetMask(MaskType.LongTime); // "14:30:00"
"25122024".SetMask(MaskType.Date); // "25/12/2024"
"122026".SetMask(MaskType.CreditCardDate); // "12/2026"
"1234567890".SetMask("(##) ####-####"); // "(12) 3456-7890"
// Remover e substituir (RemoveSpecialCharacters/ReplaceSpecialCharacters também removem espaços)
"a-b.c".Remove("-", "."); // "abc" (remove cada string)
"a-b.c".Remove("-."); // "abc" (remove cada caractere)
"café".RemoveAccentuation(); // "cafe"
"a@b#c".RemoveSpecialCharacters(); // "abc"
"a-b@c".RemoveSpecialCharacters("-"); // "a-bc"
"Olá, mundo!".ReplaceSpecialCharacters("-"); // "Ola-mundo-"
"1,234,56".KeepFirstChar(','); // "1,23456"
// Dividir e alinhar
"abcde".SplitString(); // ["abc", "de"]
"abcdefgh".SplitString(3); // ["abc", "def", "gh"]
"A".LeftRightAlign("B", 5); // "A B" (padrão: 32)
// Montar texto
"João".Format("Olá, {0}! Idade: {1}", 30); // "Olá, João! Idade: 30"
"123".InsertStart("R$ "); // "R$ 123"
"50".InsertEnd("%"); // "50%"
new[] { "a", "b" }.ArrayToHorizontalString(); // "a, b"
new[] { "a", "b" }.ArrayToVerticalString(); // "- a;\n- b;"
// Truncar, nomes e telefone
"texto longo".Truncate(5); // "texto..."
"João Carlos Silva".GetFirstAndLastName(); // "João Silva"
"(11) 98765-4321".NormalizePhoneBr(); // "5511987654321"
// Valor padrão
string nulo = null;
nulo.IfNullOrEmpty("padrão"); // "padrão"
" ".IfNullOrEmptyOrWhiteSpace("padrão"); // "padrão"
Data e Hora
var data = new DateTime(2026, 2, 1, 14, 30, 0); // domingo
var utc = new DateTime(2026, 2, 1, 17, 30, 0, DateTimeKind.Utc);
// Validações (formato brasileiro)
"14:30".IsTime(); // true
"14:30:15".IsTime(includeSeconds: true); // true
"25/12/2024".IsDate(); // true
"12/2024".IsDate(includeDays: false); // true
"25/12/2024 14:30".IsDateTime(); // true
"25/12/2024 14:30:15".IsDateTime(includeSeconds: true); // true
"01/01/2024 - 31/12/2024".IsDateRange(); // true
"01/01/2024 08:00 - 01/01/2024 18:00".IsDateTimeRange(); // true
// Intervalos
data.InRange("01/01/2026 - 31/12/2026"); // true
data.InRange("01/01/2026", "31/12/2026"); // true
data.InRange(DateRange.ThisMonth); // DateRange
data.InRange(new DateTimeRange(inicio, fim)); // DateTimeRange (considera hora)
data.DateInNextDays(0, 7); // data entre hoje e daqui a 7 dias
nascimento.BirthdayInNextDays(0, 30); // aniversário nos próximos 30 dias
nascimento.IsBirthday(); // hoje é aniversário (dia e mês)
data.IsWeekend(); // true
DayOfWeek.Monday.IsWeekend(); // false
// Conversões para string
data.ToDate(); // "01/02/2026"
data.ToDate(includeDays: false); // "02/2026"
data.ToDateTime(); // "01/02/2026 14:30"
data.ToDateTime(includeSeconds: true); // "01/02/2026 14:30:00"
data.ToTime(); // "14:30"
new TimeSpan(14, 30, 0).ToTime(includeSeconds: true); // "14:30:00"
data.ToISODate(); // "2026-02-01"
data.ToISODateTime(); // "2026-02-01 14:30:00"
// Conversões de string (null se inválido)
"25/12/2024".ToDate(); // DateTime? 25/12/2024
"12/2024".ToDate(includeDays: false); // DateTime? 01/12/2024
"25/12/2024 14:30".ToDateTime(); // DateTime?
"14:30".ToTime(); // TimeSpan? 14:30:00
"2024-12-25".ToISODate(); // DateTime?
"2024-12-25T14:30:00Z".ToISODateTime(); // DateTime? 25/12/2024 14:30:00
// Fuso horário Brasil (Unspecified é tratado como UTC)
utc.ToDateTimeBr(); // 01/02/2026 14:30 (aceita DateTime?)
utc.Br(); // atalho de ToDateTimeBr
utc.ToDateTimeBrString(); // "01/02/2026 14:30"
utc.ToDateBr(); // 01/02/2026 00:00 (aceita DateTime?)
utc.ToDateBrString(); // "01/02/2026"
utc.ToTimeBr(); // TimeSpan 14:30:00
utc.ToTimeBrString(); // "14:30"
TimeZoneInfo.Local.Br(); // TimeZoneInfo de Brasília
DateTimeBr.Now; // agora em Brasília
DateTimeBr.Today; // hoje (sem hora) em Brasília
DateTimeBr.TimeOfDay; // hora atual em Brasília
// Fuso local do sistema
utc.ToDateTimeLocal(); // converte para o fuso local
utc.ToDateTimeLocalString(); // "dd/MM/yyyy HH:mm" no fuso local
// Kind (altera apenas o Kind, sem converter o valor; aceita DateTime?)
dataDoBanco.AsUtc(); // marca como DateTimeKind.Utc
dataDoBanco.AsUnspecified(); // marca como DateTimeKind.Unspecified
// Idade
DateTime.Today.AddYears(-30).Age(); // 30
DateTime.Today.AddYears(-2).AddMonths(-3).AgeWithMonths(); // "2 anos e 3 meses"
DateTime.Today.AddMonths(-1).AgeWithMonths(); // "1 mês" (DateTime? null → "")
// Dia da semana / Mês (pt-BR)
data.ToDay(); // "Domingo"
DayOfWeek.Monday.ToDay(); // "Segunda-feira"
data.ToMonth(); // "Fevereiro"
// Limites
data.DaysInMonth(); // 28
data.EndOfDay(); // 01/02/2026 23:59:59.999
data.FirstDayOfMonth(); // 01/02/2026 00:00
data.LastDayOfMonth(); // 28/02/2026 23:59:59.999
data.FirstDayOfYear(); // 01/01/2026 00:00
data.LastDayOfYear(); // 31/12/2026 23:59:59.999
data.Min(DateTime.Today); // nunca antes de hoje (retorna a maior)
data.Max(DateTime.Today); // nunca depois de hoje (retorna a menor)
Objeto
object obj = null;
obj.IsNull(); // true
obj.NotNull(); // false
// Conversões
"123".ToInt(); // 123
"3.14".ToDouble(); // 3.14
"guid-string".ToGuid(); // Guid
"123".ToIntNullable(); // int?
// Condicionais
valor.If(condicao, novoValor);
condicao.IfElse(valorTrue, valorFalse);
item.IsNullOrNotEnabled(); // verifica propriedade "Ativo"
Número
(-5).IfNegative(0); // 0
(0).IfZero(1); // 1
(-5).IfNegativeOrZero(1); // 1
valor.MinValue(0); // não permite menor que 0
valor.MaxValue(100); // não permite maior que 100
valor.RangeValue(0, 100); // limita entre 0 e 100
Formatação (pt-BR)
1234.56.ToMoney(); // "R$ 1.234,56"
0.1575.ToPercent(); // "15,75%"
1234.56.ToNumber(); // "1.234,56"
// Converter de string formatada para número
"R$ 1.234,56".ToNumber<double>(); // 1234.56
"15,75%".ToNumber<double>(); // 15.75
Validação
// Documentos (aceita com ou sem máscara)
"123.456.789-09".IsCPF(); // true
"12345678900".IsCPF(); // false (dígito inválido)
"00.038.166/0001-05".IsCNPJ(); // true
"01310-100".IsCEP(); // true (8 dígitos)
// Contato
"user@email.com".IsEmail(); // true
"(11) 99988-7766".IsPhoneNumber(); // true (DDD + 8 ou 9 dígitos)
"1133334444".IsPhoneNumber(); // true
// Chave PIX (CPF/CNPJ só números, celular +55, e-mail ou EVP)
"12345678909".IsChavePix(); // true
"123.456.789-09".IsChavePix(); // false (CPF com máscara)
"+5511999887766".IsChavePix(); // true
"11999887766".IsChavePix(); // false (celular exige +55)
"123e4567-e89b-12d3-a456-426614174000".IsChavePix(); // true (EVP)
// Cartão de crédito
"4111 1111 1111 1111".IsCreditCard(); // true (só verifica 16 dígitos)
"12/2030".IsCreditCardDate(); // true (MM/yyyy)
"12/30".IsCreditCardDate(); // false
// Negações
"abc".NotEmail(); // true
"abc".NotCPF(); // true
"abc".NotCNPJ(); // true
"abc".NotCEP(); // true
"abc".NotPhoneNumber(); // true
"abc".NotChavePix(); // true
// Guid?
Guid? id = null;
id.IsNull(); // true
id.NotNull(); // false
id.IsEmpty(); // false (null não é Guid.Empty)
id.NotEmpty(); // true
id.IsNullOrEmpty(); // true
id.NotNullOrEmpty(); // false
Serialização JSON
// Serializar
var json = objeto.Serialize();
var json = objeto.Serialize(writeIndented: true);
// Deserializar
var obj = json.Deserialize<Produto>();
var obj = json.TryDeserialize<Produto>(); // retorna default em caso de erro
Mapeamento de Objetos
// Mapear propriedades por nome
var model = source.MapTo<TargetModel>();
// Com controle
var result = source.MapTo(target);
result.Set(x => x.Nome, s => s.FullName);
// Mapear lista
var result = sources.MapListTo(new TargetModel());
// Ignorar propriedades nulas
var result = source.MapToIgnoreNull(target);
// Atributos de controle
[MapIgnoreSource] // na propriedade do destino: não recebe valor da origem
[MapIgnoreTarget] // na propriedade da origem: não é copiada para o destino
Coleções e Listas
// Paginação
var pagina = lista.Page(pageNumber: 2, pageSize: 10);
var total = lista.TotalPages(pageSize: 10);
// Verificações
lista.IsNullOrEmpty();
lista.IsEmpty();
lista.EmptyIfNull(); // retorna vazio em vez de null
// Operações
lista.ForEach(x => x.Ativo = true);
lista.Randomize();
lista.Split(3); // divide em 3 grupos
lista.Partition(10); // divide em páginas de 10
lista.WithIndex(); // ForeachResult com Index, IsFirstItem, IsLastItem
// Filtros opcionais (ignora se valor é null)
lista.WhereOptional(x => x.Status, statusFiltro);
lista.InRange(x => x.Valor, min, max);
IQueryable
// Paginação (compatível com EF Core)
query.Page(pageNumber, pageSize);
query.TotalPages(pageSize);
// Filtros opcionais (ignora se valor é null)
query.WhereOptional(x => x.Status, statusFiltro);
query.InRange(x => x.Valor, min, max);
query.Contains(x => x.Nome, textoBusca);
Enum
public enum Status
{
[Display(Name = "Ativo", Description = "Registro ativo")]
Ativo = 1,
Inativo = 2,
[Exclude]
Removido = 3
}
// Conversão
Status.Ativo.ToInt(); // 1
Status.Ativo.ToIntString(); // "1"
1.ToEnum<Status>(); // Status.Ativo (Status?)
99.ToEnum<Status>(); // null
"ativo".ToEnum<Status>(); // Status.Ativo (case-insensitive)
"xyz".ToEnum<Status>(); // null
"Ativo".TryToEnum<Status>(out var status); // true (também compara pelo Display Name)
// Display attribute (sem atributo, retorna ToString())
Status.Ativo.GetName(); // "Ativo"
Status.Ativo.GetDescription(); // "Registro ativo"
Status.Inativo.GetDescription(); // "Inativo"
Status.Ativo.ToName(); // alias de GetName
Status.Ativo.ToDescription(); // alias de GetDescription
1.ToEnumName<Status>(); // "Ativo"
1.ToEnumDescription<Status>(); // "Registro ativo"
// Listar (atalho Enum<T>)
Enum<Status>.AsEnumerable(); // Ativo, Inativo, Removido
Enum<Status>.AsEnumerable(Status.Inativo); // Ativo, Removido
Enum<Status>.FilterExcluded(); // Ativo, Inativo (ignora [Exclude])
Enum<Status>.ToGenericList(); // GenericList<Status> (valor + GetName)
// Listar (ExtensionEnum, todos aceitam params except)
ExtensionEnum.ToList<Status>(); // [Ativo, Inativo, Removido]
ExtensionEnum.ToListInt<Status>(); // [1, 2, 3]
ExtensionEnum.ToListString<Status>(); // ["Ativo", "Inativo", "Removido"]
ExtensionEnum.ToListIntString<Status>(); // ["1", "2", "3"]
ExtensionEnum.ToListName<Status>(Status.Removido); // ["Ativo", "Inativo"]
ExtensionEnum.ToListDescription<Status>(); // ["Registro ativo", "Inativo", "Removido"]
ExtensionEnum.FilterExcluded(typeof(Status)); // IEnumerable<Enum> sem [Exclude]
Arquivo (Extensões)
// byte[] <-> Stream
var stream = bytes.ToStream(); // Stream
var memory = bytes.ToMemoryStream(); // MemoryStream (ArgumentNullException se null)
var bytes = stream.ToByteArray();
var bytes = await stream.ToByteArrayAsync();
// Base64
bytes.ToBase64String(); // "iVBORw0KGgo..."
stream.ToBase64String(); // "iVBORw0KGgo..."
bytes.ToDataBase64String(); // "data:image/png;base64,iVBORw0KGgo..." (prefixo sempre image/png)
stream.ToDataBase64String(); // "data:image/png;base64,iVBORw0KGgo..."
"iVBORw0KGgo...".FromBase64String(); // byte[]
"data:image/png;base64,iVBORw0KGgo...".FromDataBase64String(); // byte[]
"data:image/png;base64,iVBORw0KGgo...".GetBase64String(); // "iVBORw0KGgo..."
// Extensão
"data:image/png;base64,iVBORw0KGgo...".GetFileExtension(); // ".png"
"iVBORw0KGgo...".GetExtension(); // ".png" (detecta pela assinatura; "" se desconhecida)
"JVBERi0xLjQ...".GetExtension(); // ".pdf"
".png".IsImageFile(); // true (png, jpg, jpeg, bmp, gif, tiff, webp)
".PNG".IsImageFile(); // false (case-sensitive)
// Content type
"relatorio.pdf".GetContentType(); // "application/pdf"
"C:\\fotos\\foto.JPG".GetContentType(); // "image/jpeg"
"planilha.xlsx".GetContentType(); // "application/vnd.ms-excel"
"arquivo.xyz".GetContentType(); // "application/octet-stream"
"semextensao".GetContentType(); // ArgumentNullException
// Bytes -> KB/MB (int, long ou byte[])
2048.ToKilobytes(); // 2
2097152L.ToMegabytes(); // 2
bytes.ToKilobytes(); // bytes.Length / 1024
bytes.ToMegabytes(); // bytes.Length / 1024 / 1024
// KB/MB -> bytes (int, long ou double)
50.Kilobytes(); // 51200
1.5.Kilobytes(); // 1536
50.Megabytes(); // 52428800
1.5.Megabytes(); // 1572864
// Tamanho formatado (int, long ou byte[]; separador conforme cultura)
500.GetFileSize(); // "500,0 B"
2048.GetFileSize(); // "2,0 KB"
1572864L.GetFileSize(); // "1,5 MB"
bytes.GetFileSize(); // "1,5 MB"
Criptografia e Hash
// AES (chave de até 16 caracteres, IV aleatório no início do Base64)
var encrypted = "texto".AESEncrypt("chave16chars!!!");
var decrypted = encrypted.AESDecrypt("chave16chars!!!"); // "texto"
// AES-GCM 256 bits autenticado (.NET 5+; chave de qualquer tamanho, derivada via SHA256)
// Saída: Base64 de nonce (12 bytes) + tag (16 bytes) + texto cifrado. Muda a cada chamada.
var cifrado = "texto".AesGcmEncrypt(chave);
var texto = cifrado.AesGcmDecrypt(chave); // "texto" (null se chave errada, adulterado, nulo ou vazio)
// Use chave forte e aleatória (ex.: 32+ caracteres vindos da configuração).
// Para senha de usuário, use hash (JarvisPassword), não criptografia.
// Hash (null se vazio)
"texto".ToSHA1Encode(); // hex maiúsculo (40 chars)
"texto".ToSHA256Encode(); // hex maiúsculo (64 chars)
"texto".ToMD5Encode(); // hex minúsculo (32 chars)
"texto".ToSHA1Encode("ISO-8859-1"); // encoding customizado
// Base64 (iterations opcional)
var base64 = "texto".Base64Encode(); // "dGV4dG8="
var original = base64.Base64Decode(); // "texto"
"texto".Base64Encode(2).Base64Decode(2); // codifica/decodifica 2 vezes
// URL Slug (maxLength padrão 50)
"Meu Título Aqui".ToUrlSlug(); // "meu-titulo-aqui"
123.IdToSlug("Meu Título Aqui"); // "123-meu-titulo-aqui"
"123-meu-titulo-aqui".SlugToId(); // 123 (-1 se inválido)
// Ofuscar ID inteiro (SHA1 de ticks + id embutido)
var token = 42.EncrypId(); // string ofuscada (muda a cada chamada)
token.DecryptId(); // 42 (-1 se inválido; exceção se tamanho <= 40)
// Guid
Guid.NewGuid().ToId(); // "3f2504e04f8911d39a0c0305e82c3301" (formato "N")
"guid-string".ToGuid(); // Guid ou Guid.Empty se inválido
JarvisCertificate (.NET 9+)
Carrega certificado e valida vencimento, início de validade e chave privada RSA. Retorna CertificateResponse (IsSuccess, Message, Certificate, ExpirationDate).
// PEM (.crt + .key)
var result = JarvisCertificate.LoadPem("cert.crt", "cert.key");
// PFX por arquivo ou bytes
var result = JarvisCertificate.LoadPfx("cert.pfx", "senha");
var result = JarvisCertificate.LoadPfx(pfxBytes, "senha");
// Flags opcionais (padrão: MachineKeySet | Exportable)
var result = JarvisCertificate.LoadPfx("cert.pfx", "senha", X509KeyStorageFlags.UserKeySet);
if (result.IsSuccess)
{
var cert = result.Certificate; // X509Certificate2
}
else
{
var erro = result.Message; // "Certificado digital vencido em dd/MM/yyyy."
}
JarvisUrlEncryptor
Gera tokens criptografados (AES-256) para URLs contendo qualquer valor (Guid, string, int, long, enum etc.), válidos somente para o dia informado. O token é URL-safe (Base64 com - e _).
var secret = "minha-chave-secreta";
// Gerar token válido somente para hoje
var tokenId = JarvisUrlEncryptor.Encrypt(123, DateTime.Today, secret);
var tokenEmail = JarvisUrlEncryptor.Encrypt("cliente@email.com", DateTime.Today, secret);
var tokenGuid = JarvisUrlEncryptor.Encrypt(meuGuid, DateTime.Today, secret);
// Use na URL: /minha-rota?token=xxxx
// Descriptografar e validar (retorna false se o token for de outro dia ou inválido)
if (JarvisUrlEncryptor.TryDecrypt<int>(tokenId, DateTime.Today, secret, out var id))
{
// id == 123
}
// Retorna default (null, 0 etc.) se inválido
var email = JarvisUrlEncryptor.Decrypt<string>(tokenEmail, DateTime.Today, secret);
var guid = JarvisUrlEncryptor.Decrypt<Guid>(tokenGuid, DateTime.Today, secret); // Guid.Empty se inválido
HTML
"texto".Bold(); // <b>texto</b>
"texto".Italic(); // <i>texto</i>
"texto".Paragraph(); // <p>texto</p>
"texto".Link("https://..."); // <a href='https://...'>texto</a>
Claims
// Ler claims do ClaimsPrincipal
var id = User.Id();
var name = User.Name();
var roles = User.Roles();
var email = User.Email();
var isAuth = User.IsAuthenticated();
URI e Query String
var query = QueryItem.Object("nome", "João")
.AddObject("idade", 30)
.AddDate("data", DateTime.Now);
var url = query.ToUri("https://api.exemplo.com/buscar");
// https://api.exemplo.com/buscar?nome=Jo%c3%a3o&idade=30&data=2026-02-01
Atributos de Validação
// Documentos e contato (null/vazio é válido; combine com [Required])
[CPF(ErrorMessage = "CPF inválido")]
public string CPF { get; set; }
[CNPJ(ErrorMessage = "CNPJ inválido")]
public string CNPJ { get; set; }
[CPF_CNPJ(ErrorMessage = "Documento inválido")]
public string Documento { get; set; }
[CEP(ErrorMessage = "CEP inválido")]
public string CEP { get; set; }
[PhoneNumber(ErrorMessage = "Telefone inválido")]
public string Telefone { get; set; }
[ChavePix(ErrorMessage = "Chave PIX inválida")]
public string ChavePix { get; set; }
// Valores (ctor aceita int, long, float, double ou decimal; null é inválido)
[MinValue(1, ErrorMessage = "Mínimo 1")]
public int Quantidade { get; set; }
[MaxValue(100, ErrorMessage = "Máximo 100")]
public int Porcentagem { get; set; }
// Guid (null é válido; Guid.Empty é inválido)
[NotEmptyGuid(ErrorMessage = "Selecione um item")]
public Guid ItemId { get; set; }
// Listas
[NotEmptyList(ErrorMessage = "Lista não pode ser vazia")] // null válido, vazia inválida
public List<int> Itens { get; set; }
[RequiredList(ErrorMessage = "Lista obrigatória")] // null ou vazia inválida
public List<int> ItensObrigatorios { get; set; }
// Atributos de mapeamento (MapTo)
[MapIgnoreSource] // na propriedade do destino: não recebe valor da origem
[MapIgnoreTarget] // na propriedade da origem: não é copiada para o destino
// Atributo de enum
[Exclude] // no campo do enum: remove de FilterExcluded
Modelos e Respostas
ModelResponse
// Resposta simples
return ModelResponse.Success("Operação realizada");
return ModelResponse.Error("Falha na operação");
// Resposta tipada
return ModelResponse<Produto>.Success(produto);
return ModelResponse<Produto>.Error("Não encontrado");
JsonResponse
return JsonResponse.Success(item, "Salvo com sucesso");
return JsonResponse.Error("Algo deu errado");
return JsonResponse.NotAuthenticated();
return JsonResponse.NotAuthorized();
return JsonResponse.Blocked();
// Deserializar item
var produto = response.Deserialize<Produto>();
HttpResponse
return HttpResponse<Produto>.Success(produto);
return HttpResponse<Produto>.Error("Falha");
return HttpResponse<Produto, ErroDTO>.Error(erroDto);
PaginationResponse
var paginacao = new PaginationResponse<Produto>
{
PageNumber = 1,
PageSize = 10,
TotalItems = 100,
Items = produtos
};
paginacao.TotalPages; // 10
paginacao.HasNextPage; // true
TokenResponse
var token = new TokenResponse
{
Token = "jwt...",
RefreshToken = "refresh...",
ExpiresToken = DateTime.UtcNow.AddHours(1)
};
token.IsValid; // true se não expirou
Ranges
// DateRange
var range = new DateRange("01/01/2024", "31/12/2024");
range.TotalDays; // 366
range.Dates; // lista de todos os dias
DateRange.Today;
DateRange.ThisMonth;
DateRange.ThisYear;
// TimeRange
var horario = new TimeRange("08:00", "17:00");
horario.TotalHours; // 9
// DateTimeRange
var periodo = new DateTimeRange("01/01/2024 08:00", "31/12/2024 17:00");
CPF e CNPJ (Classes)
CPF cpf = "12345678900";
cpf.Masked; // "123.456.789-00"
cpf.Unmasked; // "12345678900"
cpf.DV; // "00"
cpf.IsValid; // true/false
var novoCpf = CPF.Generate();
CNPJ cnpj = "00038166000105";
cnpj.Masked; // "00.038.166/0001-05"
cnpj.IsValid; // true/false
var novoCnpj = CNPJ.Generate();
GenericItem e GenericList
var item = new GenericItem<int>(1, "Opção 1");
var lista = new GenericList<int> { item };
var item2 = new GenericItem<int, Produto>(1, "Opção", produto);
CardModel
var card = new CardModel<int>
{
Id = 1,
Title = "Título",
Subtitle = "Subtítulo",
Description = "Descrição",
Image = "url"
};
Serviços
HTTP Client
JarvisHttpClient
Wrapper IDisposable sobre HttpClient (propriedade Client).
using var http = new JarvisHttpClient("https://api.exemplo.com");
var httpTimeout = new JarvisHttpClient("https://api.exemplo.com", TimeSpan.FromSeconds(10));
var semBase = new JarvisHttpClient();
// Configuração fluente
http.BaseAddress("https://api.exemplo.com")
.Timeout(TimeSpan.FromSeconds(30))
.BearerAuthorization(jwtToken)
.AddAcceptJson()
.AddHeader("X-Custom", "valor");
// Autorização / headers
http.BasicAuthorization("usuario", "senha"); // Base64 de "usuario:senha"
http.BasicAuthorization(base64Token);
http.AddAuthorization("ApiKey", "valor");
http.AddToken("token"); // header "X-Auth-Token" (nome opcional)
http.AddHeader("X-Lista", new[] { "a", "b" });
http.AddAccept(new MediaTypeWithQualityHeaderValue("application/xml"));
http.ClearAccepts();
http.ClearHeaders();
// GET (T ou default em erro)
var produto = await http.GetAsync<Produto>("/produtos/1");
// GET / POST / PUT / DELETE com HttpResponse<T> (IsSuccess, Item, Message)
var response = await http.GetJsonAsync<Produto>("/produtos/1");
var response = await http.PostJsonAsync<Produto>("/produtos", novoProduto);
var response = await http.PutJsonAsync<Produto>("/produtos/1", produto);
var response = await http.DeleteJsonAsync<Produto>("/produtos/1");
// Erro tipado: HttpResponse<TSuccess, TError> (Item / ItemError)
var response = await http.PostJsonAsync<Produto, ErroDTO>("/produtos", novoProduto);
// POST / PUT / DELETE retornando T (CancellationToken opcional)
var criado = await http.PostAsync<Produto>("/produtos", novoProduto);
var criado = await http.PostAsync<Produto>("/produtos", novoProduto, "application/xml");
var alterado = await http.PutAsync<Produto>("/produtos/1", produto);
var removido = await http.DeleteAsync<Produto>("/produtos/1");
// Download (null em erro)
var bytes = await http.DownloadAsync("/arquivo.pdf");
// Upload multipart (campo "file")
var result = await http.UploadAsync<FileResult>("/upload", fileBytes, "foto.jpg");
var result = await http.UploadAsync<FileResult>("/upload", stream, "foto.jpg");
// Upload PUT em URL pré-assinada (Content-Type pela extensão; true se OK)
var ok = await http.UploadPreSignedURLAsync(urlAssinada, fileBytes);
var ok = await http.UploadPreSignedURLAsync(urlAssinada, stream);
var ok = await http.UploadPreSignedURLAsync(urlAssinada, @"C:\temp\foto.jpg");
Extensões de HttpClient
Os mesmos métodos acima existem como extensões de HttpClient: BaseAddress, Timeout, BearerAuthorization, BasicAuthorization, AddAuthorization, AddToken, AddHeader, GetAsync<T>, GetJsonAsync, PostAsync<T>, PostJsonAsync, PutAsync<T>, PutJsonAsync, DeleteAsync<T>, DeleteJsonAsync, DownloadAsync, UploadAsync<T> e UploadPreSignedURLAsync.
var client = new HttpClient()
.BaseAddress("https://api.exemplo.com")
.BearerAuthorization(jwtToken)
.AddHeader("X-Custom", "valor");
var produto = await client.GetAsync<Produto>("/produtos/1"); // sem token: valida status e loga erro
var produto = await client.GetAsync<Produto>("/produtos/1", ct); // com token: GetFromJsonAsync
// Conversores de HttpResponseMessage
var message = await client.GetAsync("/produtos/1");
var item = await message.ToResult<Produto>(); // T ou default (consoleLog padrão true)
var json = await message.ToJsonResponse(); // JsonResponse (erro do corpo ou StatusCode)
var resp = await message.ToHttpResponse<Produto>(); // HttpResponse<T>
var resp = await message.ToHttpResponse<Produto, ErroDTO>(consoleLog: false); // HttpResponse<TSuccess, TError>
HttpService
Extensões de HttpClient para serviços que retornam JsonResponse. Lançam HttpRequestException em falha de comunicação, ResponseException em formato inválido e OperationCanceledException ao cancelar.
// JsonResponse (CancellationToken opcional)
var json = await client.ServiceGetAsync("/produtos/1");
var json = await client.ServicePostAsync("/produtos", novoProduto);
var json = await client.ServicePostAsync("/produtos", multipartContent);
var json = await client.ServicePutAsync("/produtos/1", produto);
var json = await client.ServicePutAsync("/produtos/1", multipartContent);
var json = await client.ServiceDeleteAsync("/produtos/1");
// Download (null em erro)
var stream = await client.ServiceGetStreamAsync("/arquivo.pdf");
var bytes = await client.ServiceGetByteArrayAsync("/arquivo.pdf");
// DownloadResponse (Bytes, FileName, ContentType); nome via Content-Disposition, fallback ou URI
var download = await client.ServiceDownloadAsync("/arquivo.pdf", "relatorio.pdf");
// Upload multipart retornando JarvisFileResult
var file = await client.ServiceUploadAsync("/upload", fileBytes, "foto.jpg");
var file = await client.ServiceUploadAsync("/upload", stream, "foto.jpg");
Consulta CEP
var endereco = await ViaCEP.FindAsync("01001000");
var endereco = await OpenCEP.FindAsync("01001000");
var endereco = await AwesomeCEP.FindAsync("01001000");
// Busca por endereço (ViaCEP)
var resultados = await ViaCEP.FindAsync("SP", "São Paulo", "Paulista");
BrasilAPI
Consulta de dados públicos brasileiros via BrasilAPI.
// Consulta CNPJ
var empresa = await BrasilAPI.FindCNPJAsync("00038166000105");
empresa.Cnpj; // "00038166000105"
empresa.RazaoSocial; // razão social
empresa.NomeFantasia; // nome fantasia
empresa.NaturezaJuridica; // natureza jurídica
empresa.Porte; // porte da empresa
empresa.Cep; // CEP
empresa.Logradouro; // logradouro
empresa.Numero; // número
empresa.Complemento; // complemento
empresa.Bairro; // bairro
empresa.Municipio; // município
empresa.Uf; // UF
empresa.CodigoMunicipioIbge; // código IBGE do município
empresa.OpcaoPeloMei; // optante pelo MEI
empresa.OpcaoPeloSimples; // optante pelo Simples Nacional
empresa.CnaeFiscal; // 8599603
empresa.CnaeFiscalDescricao; // descrição do CNAE principal
empresa.Qsa; // sócios (NomeSocio, FaixaEtaria, CnpjCpfDoSocio, QualificacaoSocio, DataEntradaSociedade)
empresa.CnaesSecundarios; // CNAEs secundários (Codigo, Descricao)
empresa.RegimeTributario; // regime por ano (Ano, FormaDeTributacao)
// Lista bancos
var bancos = await BrasilAPI.GetBanksAsync();
bancos[0].Ispb; // "00000000"
bancos[0].Name; // "BCO DO BRASIL S.A."
bancos[0].Code; // 1
bancos[0].FullName; // "Banco do Brasil S.A."
bancos[0].LogoUrl; // URL do logo (SVG)
// Consulta banco pelo código
var banco = await BrasilAPI.FindBankAsync(1);
// NCM
var ncms = await BrasilAPI.GetNCMsAsync(); // todos
var busca = await BrasilAPI.SearchNCMAsync("notebook"); // por código ou descrição
var ncm = await BrasilAPI.FindNCMAsync("8471.30.12"); // por código
ncm.Codigo; // "8471.30.12"
ncm.Descricao; // descrição
ncm.DataInicio; // início da vigência
ncm.DataFim; // fim da vigência
ncm.TipoAto; // tipo do ato legal
ncm.NumeroAto; // número do ato
ncm.AnoAto; // ano do ato
// Feriados nacionais
var feriados = await BrasilAPI.GetHolidaysAsync(2026);
feriados[0].Date; // 2026-01-01
feriados[0].Name; // "Confraternização mundial"
feriados[0].Type; // "national"
E-mail (SMTP)
var mail = new JarvisMailClient("smtp.gmail.com", 587, "user@gmail.com", "senha");
// Enviar e-mail
var result = await mail.SendAsync(
to: "destino@email.com",
subject: "Assunto",
body: "<p>Corpo HTML</p>"
);
// Template com placeholders
var template = new JarvisMailTemplate("<p>Olá {nome}!</p>");
template.Replace("{nome}", "João");
OneSignal (Push Notifications)
var onesignal = new JarvisOneSignalClient("app-id", "api-key");
// Enviar notificação
var body = new JarvisOneSignalBody
{
Title = "Título",
Message = "Mensagem",
Segments = new[] { JarvisOneSignalSegments.All }
};
var response = await onesignal.SendAsync(body);
Arquivo (File)
// Upload/download com progresso
var client = new JarvisFileClient();
client.ProgressChanged += (s, e) => Console.WriteLine($"{e.Percent}%");
client.Completed += (s, e) => Console.WriteLine("Concluído");
// Operações de arquivo
var result = JarvisFile.FromBase64(base64String, "foto.jpg");
var base64 = JarvisFile.ToBase64("caminho/arquivo.pdf");
Local Storage
var config = new JarvisLocalStorageConfiguration
{
FilePath = "C:/dados",
EnableEncryption = true,
EncryptionKey = "minha-chave-16!!"
};
using var storage = new JarvisLocalStorageClient(config);
storage.Store("chave", meuObjeto);
var obj = storage.Get<MeuTipo>("chave");
storage.Exists("chave"); // true
storage.Keys(); // lista de chaves
Autenticação
JarvisAuthenticationUser
var user = new JarvisAuthenticationUser("Cookies")
{
Id = "1",
Name = "João",
Email = "joao@email.com",
Roles = new List<string> { "Admin" }
};
user.SetItem(meuObjeto); // serializa objeto como claim Item
user.AddOther("custom_claim", "valor");
JarvisClaimTypes
JarvisClaimTypes.Id // claim de ID
JarvisClaimTypes.Name // claim de nome
JarvisClaimTypes.Email // claim de e-mail
JarvisClaimTypes.Role // claim de role
JarvisClaimTypes.ClientId // claim de client ID
JarvisClaimTypes.JwtName // "unique_name" (JWT)
JarvisClaimTypes.JwtRole // "role" (JWT)
JWT Options
var options = new JarvisJwtOptions
{
Issuer = "minha-app",
Audience = "minha-api",
SecretKey = "chave-secreta-32-chars!!!!!!!!!",
Expiration = TimeSpan.FromHours(1)
};
Utilitários
Gerador
var senha = JarvisGenerator.Password(8, PasswordType.Mixed);
var senhaDiaria = JarvisGenerator.DailyPassword(); // 6 dígitos baseado na data
var cpf = JarvisGenerator.CPF();
var cnpj = JarvisGenerator.CNPJ();
var texto = JarvisGenerator.LoremIpsum(100);
Password (PBKDF2/SHA256)
var hash = JarvisPassword.Hash("minha-senha");
var valido = JarvisPassword.Verify("minha-senha", hash); // true
Haversine (Distância Geográfica)
var km = JarvisHaversine.ToKilometers(lat1, lng1, lat2, lng2);
var metros = JarvisHaversine.ToMeters(coord1, coord2);
var milhas = JarvisHaversine.ToMiles(coord1, coord2);
Timer
var elapsed = JarvisTimer.Elapsed(() => MinhaOperacao());
var ms = JarvisTimer.ElapsedMilliseconds(() => MinhaOperacao());
var ms = await JarvisTimer.ElapsedMilliseconds(async () => await MinhaOperacaoAsync());
Log
JarvisLog.Debug("mensagem");
JarvisLog.Info("mensagem");
JarvisLog.Warn("mensagem");
JarvisLog.Error("mensagem");
JarvisLog.Exception(ex);
Matemática
JarvisMath.Percent(10, 100); // 10.0 (10%)
JarvisMath.CalculatePercentage(200, 15); // 30.0 (15% de 200)
JarvisMath.AddPercentage(100, 10); // 110.0
JarvisMath.SubtractPercentage(100, 10); // 90.0
Cor
JarvisColor.Combine("#FF0000", "#0000FF"); // combina cores pela média RGB
JarvisColor.HexToRgb("#FF5500"); // "255, 85, 0"
JarvisColor.HexToRgba("#FF5500", 0.5); // "255, 85, 0, 0.5"
Conversões de Unidade
JarvisConverter.MmToPixels(10, 96); // milímetros para pixels
JarvisConverter.PixelsToMm(100, 96); // pixels para milímetros
Diretórios e Arquivos (Helper)
JarvisDirectoryHelper.CreateIfNotExists("C:/minha-pasta");
JarvisDirectoryHelper.GetOrCreate("dados", "C:/base");
JarvisDirectoryHelper.GetOrCreateHidden("dados-ocultos");
JarvisFileHelper.SetHiddenAttribute("C:/arquivo.txt", true);
Estados e Meses (Brasil)
EstadosBrasil.Lista(); // dicionário "SP" => "São Paulo"
EstadosBrasil.Siglas(); // ["AC", "AL", ..., "TO"]
EstadosBrasil.Nomes(); // ["Acre", "Alagoas", ..., "Tocantins"]
MesesAno.Lista(); // ["Janeiro", ..., "Dezembro"]
Structs
// Meses do ano
var meses = new Months(2024);
meses.January; // 01/01/2024
meses.December; // 01/12/2024
// DateTime Brasil
DateTimeBr.Now; // agora em horário de Brasília
DateTimeBr.Today; // hoje em horário de Brasília
// Enum tipado
var valores = Enum<MeuEnum>.AsEnumerable();
Converters JSON
// Converters para System.Text.Json
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringDateConverter()); // "yyyy-MM-dd"
options.Converters.Add(new JsonStringDateTimeConverter()); // "yyyy-MM-dd HH:mm:ss"
options.Converters.Add(new JsonStringDoubleConverter()); // aceita string ou número
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Drawing.Common (>= 10.0.13)
- System.Net.Http.Json (>= 10.0.13)
-
net10.0
- No dependencies.
-
net5.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (10)
Showing the top 5 NuGet packages that depend on Jarvis.Toolkit:
| Package | Downloads |
|---|---|
|
Jarvis.Blazor
Biblioteca de componentes para Blazor. |
|
|
Jarvis.Components.Web.Mvc.Core
Biblioteca de componentes para WEB MVC Core. |
|
|
Jarvis.Maui
Biblioteca de componentes para Maui. |
|
|
Jarvis.WebApi
Biblioteca de componentes para API Web. |
|
|
Jarvis.Blazor.Mud
Biblioteca de componentes para MudBlazor. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.2.7 | 47 | 10/18/2026 |
| 1.2.2.6 | 45 | 10/18/2026 |
| 1.2.2.5 | 56 | 10/17/2026 |
| 1.2.2.4 | 59 | 10/17/2026 |
| 1.2.2.3 | 134 | 9/30/2026 |
| 1.2.2.2 | 447 | 7/23/2026 |
| 1.2.2.1 | 128 | 7/12/2026 |
| 1.2.2 | 130 | 7/10/2026 |
| 1.2.1.9 | 150 | 5/28/2026 |
| 1.2.1.8 | 191 | 5/22/2026 |
| 1.2.1.7 | 201 | 5/16/2026 |
| 1.2.1.6 | 169 | 5/13/2026 |
| 1.2.1.5 | 134 | 5/4/2026 |
| 1.2.1.4 | 262 | 4/3/2026 |
| 1.2.1.3 | 235 | 3/25/2026 |
| 1.2.1.2 | 214 | 3/16/2026 |
| 1.2.1.1 | 174 | 3/8/2026 |
| 1.2.1 | 189 | 3/8/2026 |
| 1.2.0.9 | 182 | 3/4/2026 |
| 1.2.0.8 | 155 | 3/2/2026 |