Como integrar validação de CPF em aplicações Blazor WebAssembly

Aprenda a integrar validação de CPF em Blazor WebAssembly usando HttpClient e componentes Razor com a API da CPFHub.io.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como integrar validação de CPF em aplicações Blazor WebAssembly

O Blazor WebAssembly permite executar código C# diretamente no navegador, eliminando a necessidade de JavaScript para a lógica da aplicação. Para integrar validação de CPF em tempo real, você configura um HttpClient tipado com injeção de dependência, cria um serviço que chama GET https://api.cpfhub.io/cpf/{CPF} com o header x-api-key, e consome o resultado em componentes Razor reutilizáveis. A latência típica da API é de ~900ms, então configure o timeout do cliente acima desse valor. Para produção, use um backend BFF para proteger a chave de API, pois o código WASM roda inteiramente no navegador.


1. Pré-requisitos


2. Crie os modelos de dados

Defina as classes para representar a resposta da API:

// Models/CpfResponse.cs
using System.Text.Json.Serialization;

namespace CpfValidatorBlazor.Models;

public class CpfApiResponse
{
    [JsonPropertyName("success")]
    public bool Success { get; set; }

    [JsonPropertyName("data")]
    public CpfData? Data { get; set; }
}

public class CpfData
{
    [JsonPropertyName("cpf")]
    public string Cpf { get; set; } = string.Empty;

    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("nameUpper")]
    public string NameUpper { get; set; } = string.Empty;

    [JsonPropertyName("gender")]
    public string Gender { get; set; } = string.Empty;

    [JsonPropertyName("birthDate")]
    public string BirthDate { get; set; } = string.Empty;

    [JsonPropertyName("day")]
    public int Day { get; set; }

    [JsonPropertyName("month")]
    public int Month { get; set; }

    [JsonPropertyName("year")]
    public int Year { get; set; }
}

3. Crie o serviço de consulta

Implemente o serviço usando HttpClient com injeção de dependência:

// Services/CpfHubService.cs
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using CpfValidatorBlazor.Models;

namespace CpfValidatorBlazor.Services;

public interface ICpfHubService
{
    Task<CpfData> ConsultarCpfAsync(string cpf, CancellationToken ct = default);
}

public class CpfHubService : ICpfHubService
{
    private readonly HttpClient _httpClient;

    public CpfHubService(HttpClient httpClient)
    {
    _httpClient = httpClient;
    }

    public async Task<CpfData> ConsultarCpfAsync(string cpf, CancellationToken ct = default)
    {
    var cpfLimpo = Regex.Replace(cpf, @"\D", "");

    if (cpfLimpo.Length != 11)
    throw new ArgumentException("CPF deve conter exatamente 11 dígitos.");

    using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
    cts.CancelAfter(TimeSpan.FromSeconds(5));

    try
    {
    var response = await _httpClient.GetAsync($"cpf/{cpfLimpo}", cts.Token);

    if (response.IsSuccessStatusCode)
    {
    var resultado = await response.Content
    .ReadFromJsonAsync<CpfApiResponse>(cancellationToken: cts.Token);

    if (resultado?.Success == true && resultado.Data != null)
    return resultado.Data;

    throw new InvalidOperationException("Resposta inesperada da API.");
    }

    var mensagem = (int)response.StatusCode switch
    {
    400 => "CPF com formato inválido.",
    401 => "Chave de API inválida ou ausente.",
    404 => "CPF não encontrado na base de dados.",
    _ => $"Erro HTTP {(int)response.StatusCode}."
    };

    throw new HttpRequestException(mensagem);
    }
    catch (OperationCanceledException)
    {
    throw new TimeoutException("Timeout ao consultar a API da CPFHub.");
    }
    }
}

4. Configure a injeção de dependência

Registre o serviço no Program.cs:

// Program.cs
using CpfValidatorBlazor.Services;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");

// Configurar HttpClient para a API CPFHub
builder.Services.AddHttpClient<ICpfHubService, CpfHubService>(client =>
{
    client.BaseAddress = new Uri("https://api.cpfhub.io/");
    client.DefaultRequestHeaders.Add("x-api-key", "SUA_CHAVE_DE_API");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});

await builder.Build().RunAsync();

5. Crie o componente de formulário

Implemente o formulário com validação e data binding:

// Models/CpfFormModel.cs
using System.ComponentModel.DataAnnotations;

namespace CpfValidatorBlazor.Models;

public class CpfFormModel
{
    [Required(ErrorMessage = "CPF é obrigatório.")]
    [StringLength(14, MinimumLength = 11, ErrorMessage = "CPF deve ter 11 dígitos.")]
    public string Cpf { get; set; } = string.Empty;
}

6. Crie a página de consulta

Implemente a página Razor com o componente de consulta:

@* Pages/ConsultaCpf.razor *@
@page "/consulta-cpf"
@using CpfValidatorBlazor.Models
@using CpfValidatorBlazor.Services
@inject ICpfHubService CpfService

<h2>Consulta de CPF</h2>

<EditForm Model="@formModel" OnValidSubmit="@ConsultarCpf">
    <DataAnnotationsValidator />

    <div class="mb-3">
    <label for="cpf" class="form-label">CPF</label>
    <InputText id="cpf"
    class="form-control"
    @bind-Value="formModel.Cpf"
    placeholder="000.000.000-00"
    maxlength="14"
    @oninput="AplicarMascara" />
    <ValidationMessage For="@(() => formModel.Cpf)" />
    </div>

    <button type="submit" class="btn btn-primary" disabled="@isLoading">
    @if (isLoading)
    {
    <span class="spinner-border spinner-border-sm" role="status"></span>
    <span> Consultando...</span>
    }
    else
    {
    <span>Consultar CPF</span>
    }
    </button>
</EditForm>

@if (resultado != null)
{
    <div class="card mt-4 border-success">
    <div class="card-header bg-success text-white">
    CPF Encontrado
    </div>
    <div class="card-body">
    <p><strong>Nome:</strong> @resultado.Name</p>
    <p><strong>CPF:</strong> @resultado.Cpf</p>
    <p><strong>Genero:</strong> @resultado.Gender</p>
    <p><strong>Nascimento:</strong> @resultado.BirthDate</p>
    </div>
    </div>
}

@if (!string.IsNullOrEmpty(erro))
{
    <div class="alert alert-danger mt-4">
    @erro
    </div>
}

@code {
    private CpfFormModel formModel = new();
    private CpfData? resultado;
    private string? erro;
    private bool isLoading;

    private async Task ConsultarCpf()
    {
    isLoading = true;
    resultado = null;
    erro = null;

    try
    {
    resultado = await CpfService.ConsultarCpfAsync(formModel.Cpf);
    }
    catch (ArgumentException ex)
    {
    erro = ex.Message;
    }
    catch (TimeoutException ex)
    {
    erro = ex.Message;
    }
    catch (HttpRequestException ex)
    {
    erro = ex.Message;
    }
    catch (Exception ex)
    {
    erro = $"Erro inesperado: {ex.Message}";
    }
    finally
    {
    isLoading = false;
    }
    }

    private void AplicarMascara(ChangeEventArgs e)
    {
    var valor = e.Value?.ToString() ?? "";
    var numeros = System.Text.RegularExpressions.Regex.Replace(valor, @"\D", "");
    if (numeros.Length > 11) numeros = numeros[..11];

    formModel.Cpf = numeros.Length switch
    {
    > 9 => $"{numeros[..3]}.{numeros[3..6]}.{numeros[6..9]}-{numeros[9..]}",
    > 6 => $"{numeros[..3]}.{numeros[3..6]}.{numeros[6..]}",
    > 3 => $"{numeros[..3]}.{numeros[3..]}",
    _ => numeros
    };
    }
}

7. Segurança da chave de API

Em Blazor WebAssembly, o código C# roda no navegador, portanto a chave de API fica exposta. Para produção, use um backend BFF (Backend for Frontend):

// No servidor Blazor Server ou API separada:
// Controllers/CpfProxyController.cs
[ApiController]
[Route("api/[controller]")]
public class CpfProxyController : ControllerBase
{
    private readonly ICpfHubService _cpfService;

    public CpfProxyController(ICpfHubService cpfService)
    {
    _cpfService = cpfService;
    }

    [HttpGet("{cpf}")]
    public async Task<IActionResult> Consultar(string cpf)
    {
    try
    {
    var dados = await _cpfService.ConsultarCpfAsync(cpf);
    return Ok(new { success = true, data = dados });
    }
    catch (Exception ex)
    {
    return BadRequest(new { success = false, error = ex.Message });
    }
    }
}

8. Boas práticas

  • HttpClient -- Use IHttpClientFactory para gerenciar o ciclo de vida do HttpClient e evitar problemas de socket.

  • Timeout -- Configure timeout via CancellationTokenSource para controlar o tempo máximo da requisição. A latência da API CPFHub.io é de ~900ms; configure o timeout acima desse valor.

  • Segurança WASM -- Em Blazor WebAssembly, a chave de API fica acessível no navegador. Use um backend proxy para produção.

  • Validação -- Use DataAnnotationsValidator para validação no lado do cliente antes de enviar a requisição.

  • Estado -- Use o padrão de componentes Razor com @code para gerenciar o estado da UI de forma reativa.

  • LGPD -- A API da CPFHub.io é 100% compatível com a LGPD. Em aplicações web, implemente consentimento explícito para coleta de dados pessoais.


Perguntas frequentes

Como o Blazor WebAssembly faz requisições HTTP para uma API externa?

O Blazor WebAssembly usa o HttpClient do .NET, que internamente delega ao fetch do navegador via interop JavaScript. Você registra um HttpClient tipado no Program.cs com AddHttpClient<TService>, define a BaseAddress e os headers padrão — incluindo x-api-key — e injeta o serviço nos componentes Razor via @inject. O fluxo é idêntico ao de uma API .NET convencional, com a diferença de que tudo roda no contexto do navegador.

A chave de API fica segura em uma aplicação Blazor WebAssembly?

Não em produção. Como o código WASM roda inteiramente no navegador, qualquer valor definido em tempo de compilação fica acessível via ferramentas de desenvolvedor. A abordagem recomendada é um backend BFF (Backend for Frontend): o Blazor chama seu próprio servidor, que mantém a x-api-key em variáveis de ambiente e faz o proxy para api.cpfhub.io. A documentação de segurança do Blazor detalha os padrões recomendados.

O que acontece se o limite de consultas do plano gratuito for atingido?

A API CPFHub.io não bloqueia as requisições ao atingir o limite. O plano gratuito inclui 50 consultas por mês e, ao ultrapassá-lo, cada consulta adicional é cobrada a R$0,15. Isso permite que aplicações em desenvolvimento e produção continuem funcionando sem interrupção. Para volumes previsíveis, o plano Pro oferece 1.000 consultas mensais por R$149.

Quanto tempo leva para integrar a API CPFHub.io em um projeto Blazor existente?

A integração básica leva menos de 30 minutos: adicione o serviço no Program.cs, crie a classe de modelo correspondente ao JSON retornado e injete o serviço no componente Razor. A latência típica da API é de ~900ms, então configure o CancellationTokenSource com um timeout de pelo menos 5 segundos para absorver variações de rede.



Conclusão

Integrar a API da CPFHub.io

Cadastre-se em cpfhub.io

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

Sobre a redação

Redação CPFHub.io

Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.

WhatsAppFale conosco via WhatsApp