Jarvis.WebPages 2.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Jarvis.WebPages --version 2.0.0
                    
NuGet\Install-Package Jarvis.WebPages -Version 2.0.0
                    
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="Jarvis.WebPages" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jarvis.WebPages" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Jarvis.WebPages" />
                    
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 Jarvis.WebPages --version 2.0.0
                    
#r "nuget: Jarvis.WebPages, 2.0.0"
                    
#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 Jarvis.WebPages@2.0.0
                    
#: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=Jarvis.WebPages&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Jarvis.WebPages&version=2.0.0
                    
Install as a Cake Tool

Jarvis.WebPages

Biblioteca de componentes TagHelper para construção de formulários em Razor Pages e MVC.

Instalação

Requer .NET 10.

dotnet add package Jarvis.WebPages

Registre os TagHelpers no _ViewImports.cshtml:

@addTagHelper *, Jarvis.WebPages

Adicione o script de máscaras e formatação no layout:

<script src="/_content/Jarvis.WebPages/js/init.js"></script>

Componentes

Propriedades Comuns (BaseTagHelper)

Propriedade Tipo Descrição
asp-for ModelExpression Binding com a propriedade do modelo
asp-readonly bool Torna o campo somente leitura
asp-disabled bool Desabilita o campo
asp-name string Sobrescreve o nome do campo

Todos os componentes geram automaticamente: label, input, texto descritivo (via [Display(Description)]) e mensagem de validação.


FormText

Campo de texto simples.

<form-text asp-for="Nome" asp-col-css="col-md-6" asp-placeholder="Digite o nome" />
Propriedade Tipo Padrão Descrição
asp-col-css string col-md-12 Classe CSS da coluna
asp-input-css string Classe CSS adicional no input
asp-placeholder string Placeholder do campo

FormTextArea

Campo de texto multilinha.

<form-text-area asp-for="Observacao" asp-col-css="col-md-12" asp-placeholder="Descreva..." />
Propriedade Tipo Padrão Descrição
asp-col-css string col-md-12 Classe CSS da coluna
asp-input-css string Classe CSS adicional no input
asp-placeholder string Placeholder do campo

FormPassword

Campo de senha.

<form-password asp-for="Senha" asp-col-css="col-md-6" />
Propriedade Tipo Padrão Descrição
asp-col-css string col-md-12 Classe CSS da coluna
asp-input-css string Classe CSS adicional no input

FormDate

Campo de data com suporte a date picker nativo ou input com máscara dd/mm/aaaa.

<form-date asp-for="DataNascimento" asp-col-css="col-md-4" asp-show-picker="false" />
Propriedade Tipo Padrão Descrição
asp-input-css string Classe CSS adicional no input
asp-col-css string col-md-12 Classe CSS da coluna
asp-max DateTime? Data máxima permitida
asp-min DateTime? Data mínima permitida
asp-on-change string Nome da função JS chamada ao alterar a data
asp-show-picker bool true true = date picker nativo, false = input texto

Exemplo com asp-on-change

<form-date asp-for="DataInicio"
           asp-col-css="col-md-4"
           asp-show-picker="true"
           asp-on-change="onDataInicioChange" />

<script>
    function onDataInicioChange(value) {
        // value = "2024-06-15" (formato ISO)
        console.log('Data selecionada:', value);
    }
</script>

Quando asp-show-picker="true", a função é chamada via onchange do input. Quando asp-show-picker="false", é chamada via data-onchange após o preenchimento completo da data.


FormDateTime

Campo de data e hora (datetime-local).

<form-date-time asp-for="DataHora" asp-col-css="col-md-6" />
Propriedade Tipo Padrão Descrição
asp-input-css string Classe CSS adicional no input
asp-col-css string col-md-12 Classe CSS da coluna
asp-max DateTime? Data/hora máxima permitida
asp-min DateTime? Data/hora mínima permitida

FormSelect

Campo de seleção (dropdown).

<form-select asp-for="CidadeId"
             asp-items="Model.Cidades"
             asp-value-field="Id"
             asp-text-field="Nome"
             asp-placeholder="Selecione a cidade"
             asp-on-change="onCidadeChange" />
Propriedade Tipo Padrão Descrição
asp-input-css string Classe CSS adicional no select
asp-col-css string col-md-12 Classe CSS da coluna
asp-items IEnumerable Lista de itens para popular o select
asp-on-change string Nome da função JS chamada ao alterar o valor
asp-text-field string Text Nome da propriedade usada como texto
asp-value-field string Value Nome da propriedade usada como value
asp-placeholder string Selecionar... Texto da opção vazia

Exemplo com asp-on-change

<form-select asp-for="EstadoId"
             asp-items="Model.Estados"
             asp-value-field="Id"
             asp-text-field="Nome"
             asp-on-change="onEstadoChange" />

<script>
    function onEstadoChange(value) {
        // value = id do estado selecionado
        console.log('Estado selecionado:', value);

        // Exemplo: carregar cidades do estado via AJAX
        fetch(`/api/cidades?estadoId=${value}`).
            then(r => r.json()).
            then(cidades => {
                // popular outro select de cidades
            });
    }
</script>

FormNumeric

Campo numérico com formatação automática (dinheiro, percentual, decimal, inteiro).

<form-numeric asp-for="Valor" asp-type="Money" asp-precision="2" asp-col-css="col-md-4" />
Propriedade Tipo Padrão Descrição
asp-col-css string col-md-12 Classe CSS da coluna
asp-input-css string Classe CSS adicional no input
asp-precision int 2 Casas decimais
asp-type NumericType Decimal Tipo de formatação

NumericType

Valor Formatação
Money R$ 1.234,56
Percent 12,34%
Decimal 1.234,56
Integer 1.234

FormMask

Campo com máscara de entrada (aceita apenas números, formatados automaticamente).

<form-mask asp-for="CPF" asp-type="CPF" asp-col-css="col-md-4" />
<form-mask asp-for="Codigo" asp-type="Custom" asp-mask="##.###-##" />
<form-mask asp-for="Quantidade" asp-type="OnlyNumbers" />
Propriedade Tipo Padrão Descrição
asp-col-css string col-md-12 Classe CSS da coluna
asp-input-css string Classe CSS adicional no input
asp-type MaskType CPF Tipo de máscara
asp-on-complete string Nome da função JS chamada ao completar a máscara
asp-mask string Máscara personalizada (usado com Custom)

MaskType

Valor Máscara Exemplo
CPF ###.###.###-## 123.456.789-00
CNPJ ##.###.###/####-## 12.345.678/0001-90
CPF_CNPJ Automático por tamanho CPF ou CNPJ
CEP #####-### 12345-678
PhoneNumber (##) #####-#### (11) 99876-5432
OnlyNumbers Sem máscara, só dígitos 123456
Custom Definida por asp-mask Conforme o pattern

Exemplo com asp-on-complete

O callback é disparado quando o usuário termina de preencher todos os dígitos da máscara.

<form-mask asp-for="CPF"
           asp-type="CPF"
           asp-col-css="col-md-4"
           asp-on-complete="onCpfComplete" />

<script>
    function onCpfComplete(value) {
        // value = "123.456.789-00" (com máscara)
        console.log('CPF preenchido:', value);

        // Exemplo: buscar dados do cliente pelo CPF
        const cpf = value.replace(/\D/g, '');
        fetch(`/api/clientes?cpf=${cpf}`).
            then(r => r.json()).
            then(cliente => {
                // preencher campos do formulário
            });
    }
</script>
<form-mask asp-for="CEP"
           asp-type="CEP"
           asp-col-css="col-md-3"
           asp-on-complete="onCepComplete" />

<script>
    function onCepComplete(value) {
        // value = "12345-678"
        const cep = value.replace(/\D/g, '');
        fetch(`https://viacep.com.br/ws/${cep}/json/`).
            then(r => r.json()).
            then(endereco => {
                document.querySelector('[name="Logradouro"]').value = endereco.logradouro;
                document.querySelector('[name="Bairro"]').value = endereco.bairro;
                document.querySelector('[name="Cidade"]').value = endereco.localidade;
            });
    }
</script>

Máscara Custom

Use # para representar um dígito numérico. Qualquer outro caractere é inserido automaticamente como separador fixo. O asp-on-complete também funciona com máscaras customizadas.

<form-mask asp-for="Protocolo"
           asp-type="Custom"
           asp-mask="####/####-##"
           asp-on-complete="onProtocoloComplete" />

<script>
    function onProtocoloComplete(value) {
        // value = "2024/0001-01"
        console.log('Protocolo preenchido:', value);
    }
</script>

Exemplos de patterns:

##.###-##    →  12.345-67
####/####    →  2024/0001
###-##       →  123-45
####/####-## →  2024/0001-01

Alerts

Componente de alertas Bootstrap que exibe mensagens armazenadas via TempData. Renderiza alertas de info (azul), sucesso (verde), aviso (amarelo) e erro (vermelho).

Na view (layout ou página):

<alerts></alerts>

No PageModel:

// Alerta informativo (azul)
this.Info("Operação realizada.");

// Alerta de sucesso (verde)
this.Success("Registro salvo com sucesso!");

// Alerta de aviso (amarelo)
this.Warning("Atenção: campo opcional não preenchido.");

// Alerta de erro (vermelho)
this.Error("Falha ao salvar o registro.");

return RedirectToPage();

As mensagens são exibidas automaticamente na próxima renderização da página e descartadas após a exibição.


Helpers

is-visible

Controla a visibilidade de qualquer elemento HTML. Quando false, o elemento é completamente removido do output.

<div is-visible="Model.ExibirDetalhes">
    Conteúdo visível apenas quando ExibirDetalhes for true.
</div>

<button is-visible="Model.PodeExcluir">Excluir</button>

disabled

Adiciona o atributo disabled a qualquer elemento HTML quando a condição é true.

<button disabled="Model.Processando">Salvar</button>
<input disabled="!Model.PodeEditar" />

ButtonWhatsApp

Botão flutuante de WhatsApp com animação de pulso. Renderiza um ícone fixo no canto inferior direito que abre uma conversa no WhatsApp.

<button-whats-app number="5511999999999" text="Olá, preciso de ajuda!" />
Propriedade Tipo Descrição
number string Número do WhatsApp com código do país (sem +, espaços ou traços)
text string Texto pré-preenchido na mensagem

Fab

Botão de ação flutuante fixo no canto inferior direito, visível apenas no mobile — fica oculto a partir de 768px. Renderiza um link circular com ícone Font Awesome.

<fab href="/agenda/agendar" icon="fa-plus" label="Agendar compromisso" />
Propriedade Tipo Descrição
href string URL de destino ao clicar
icon string Classe do ícone Font Awesome, renderizado como fa-solid {icon}
label string Texto acessível do botão (aria-label)

Requer Font Awesome carregado na página. A cor de fundo usa a variável CSS --c-primary, com fallback #003299.


Extensions

Métodos de extensão disponíveis para uso no PageModel e HttpContext.

Validação

if (ModelState.NotValid())
{
    return Page();
}

Listas para Select

Converte uma GenericList<T> do Jarvis.Toolkit em IEnumerable<SelectListItem>, pronta para o asp-items do FormSelect.

Estados = _service.ListarEstados().ToSelectListItem();
<form-select asp-for="IdEstado" asp-items="Model.Estados" />

IP e Dispositivo do Cliente

var ip = HttpContext.GetIpAddress();
var device = HttpContext.GetDevice();

GetIpAddress normaliza endereços IPv4 recebidos em formato mapeado (::ffff:189.10.20.30) para IPv4 puro. Endereços IPv6 reais são mantidos intactos, então a coluna de IP no banco precisa comportar 45 caracteres.

GetDevice retorna o cabeçalho User-Agent já com Trim(). Devolve string vazia quando o cabeçalho não é enviado.

Atrás de Proxy Reverso

Com IIS/ARR, Docker Swarm ou nginx na frente, GetIpAddress devolve o IP do proxy, não o do cliente. Para obter o IP real, registre o processamento dos cabeçalhos encaminhados:

builder.Services.AddJarvisIpCliente();

var app = builder.Build();

app.UseJarvisIpCliente(); // primeira linha do pipeline, antes de auth e HTTPS redirect

Isso configura X-Forwarded-For e X-Forwarded-Proto com ForwardLimit = 1 (um único proxy na frente). Sem parâmetro, aceita cabeçalhos vindos das faixas privadas 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 e loopback.

Informando os proxies explicitamente, somente esses endereços são aceitos:

builder.Services.AddJarvisIpCliente("192.168.1.50");

Segurança: confiar em faixas inteiras permite que qualquer host daquela rede forje o cabeçalho X-Forwarded-For e se passe por outro IP — num cluster Swarm, isso inclui qualquer container. Se o IP for usado para bloqueio, rate limit ou auditoria, passe o endereço do proxy explicitamente.

Notas de infraestrutura:

  • O IIS/ARR envia X-Forwarded-For por padrão, mas não o X-Forwarded-Proto — este exige uma regra de rewrite definindo a server variable HTTP_X_FORWARDED_PROTO. Sem ela, UseHttpsRedirection pode entrar em loop.
  • No Docker Swarm, o ingress faz SNAT e altera apenas o IP de origem (L3); o cabeçalho X-Forwarded-For passa intacto. Como o gateway do ingress fica em 10.0.0.0/8, o modo padrão de publicação funciona. Publicar com mode: host só é necessário para obter o IP real sem depender de cabeçalho.
  • Se um dia entrar outro proxy na frente (Cloudflare, nginx), o ForwardLimit precisa subir para 2.

Autenticação

// Login
await HttpContext.LoginAsync(user);

// Logout
await HttpContext.LogoutAsync();

// Atualizar uma claim
await HttpContext.UpdateClaimAsync("Role", "Admin");

// Atualizar múltiplas claims
await HttpContext.UpdateClaimsAsync(
    new JarvisClaim("Role", "Admin"),
    new JarvisClaim("Name", "João")
);

// Reemitir o cookie a partir de uma identidade já montada
await HttpContext.RefreshLoginAsync(identity);
Método Descrição
LoginAsync Cria a identidade a partir de JarvisAuthenticationUser e autentica
LogoutAsync Encerra a sessão de autenticação
RefreshLoginAsync Reemite o cookie a partir de um ClaimsIdentity existente
UpdateClaimAsync Substitui uma claim e reemite o cookie
UpdateClaimsAsync Substitui várias claims e reemite o cookie

UpdateClaimAsync e UpdateClaimsAsync reemitem o cookie de autenticação — o usuário permanece logado, mas HttpContext.User na requisição atual continua com os valores antigos. A mudança só aparece na próxima requisição.

Todos emitem o cookie com IsPersistent = true, ou seja, a sessão sobrevive ao fechamento do navegador. Não há opção de sessão temporária.

Sessão

// Armazenar string
HttpContext.SetSession("Token", "abc123");

// Armazenar objeto (serializado automaticamente)
HttpContext.SetSession("Carrinho", carrinho);

// Recuperar string
var token = HttpContext.GetSession("Token");

// Recuperar objeto (deserializado automaticamente)
var carrinho = HttpContext.GetSession<Carrinho>("Carrinho");

// Remover
HttpContext.DeleteSession("Token");
Product Compatible and additional computed target framework versions.
.NET 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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1 40 9/17/2026
2.0.0.9 78 9/13/2026
2.0.0.8 108 8/19/2026
2.0.0.7 100 8/19/2026
2.0.0.6 104 8/17/2026
2.0.0.5 107 8/16/2026
2.0.0.4 104 8/16/2026
2.0.0.3 100 8/15/2026
2.0.0.2 96 8/10/2026
2.0.0.1 111 8/2/2026
2.0.0 112 8/1/2026
1.0.1.6 117 5/19/2026
1.0.1.5 140 2/1/2026
1.0.1.4 126 1/28/2026
1.0.1.3 223 11/28/2025
1.0.1.2 328 11/13/2025
1.0.1.1 233 10/1/2025
1.0.1 167 7/11/2025
1.0.0.9 348 3/26/2025
1.0.0.8 188 2/13/2025
Loading failed