# 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.

**Publicado:** 15/07/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-integrar-validacao-de-cpf-em-aplicacoes-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

* **.NET 8.0+ SDK** instalado. Consulte os [requisitos de instalação do Blazor](https://learn.microsoft.com/en-us/aspnet/core/blazor/tooling) na documentação oficial da Microsoft.

* Um projeto Blazor WebAssembly: `dotnet new blazorwasm -n CpfValidatorBlazor`.

* Uma conta gratuita na [**CPFHub.io**](https://www.cpfhub.io/)

---

## 2. Crie os modelos de dados

Defina as classes para representar a resposta da API:

```csharp
// 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:

```csharp
// 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`:

```csharp
// 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:

```csharp
// 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:

```razor
@* 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):

```csharp
// 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](https://learn.microsoft.com/en-us/aspnet/core/blazor/security/) 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.

---

### Leia também

- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)
- [Boas práticas para consumir APIs de CPF de forma segura](https://cpfhub.io/blog/boas-praticas-consumir-apis-cpf-segura)
- [Autenticação em APIs REST: como garantir segurança na consulta de CPF](https://cpfhub.io/blog/autenticacao-apis-rest-seguranca-consulta-cpf)
- [Como consumir API de CPF em C# com HttpClient e .NET 8](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-csharp-com-httpclient-e-dotnet-8)

---

## Conclusão

Integrar a API da [**CPFHub.io**](https://www.cpfhub.io/)

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/)

