Skip to main content

HttpContext em .NET | Csharp

  • HttpContext em .NET | Csharp

info

Vídeo Explicativo: 🔗 Clique aqui


Por que é mais rápido? (Explicação Técnica)

1. Evita o custo do model binding do ASP.NET Core

Quando você coloca um parâmetro como:

[HttpPost]
public IActionResult Processar(MeuObjeto obj) { ... }

O ASP.NET Core faz um processo chamado Model Binding, que envolve:

  • Ler o body (stream)
  • Bufferizar o conteúdo
  • Detectar tipo e metadados
  • Aplicar validações de binding
  • Rodar analisadores (annotations, binders especiais)
  • Desserializar via System.Text.Json
  • Popular erros de model state
  • Eventuais conversões extras

Essa cadeia tem várias etapas, filtros e abstrações — mesmo quando você não precisa delas.

Quando você usa:

public async Task<IResult> Processar(HttpContext ctx)

E manualmente faz:

var body = await new StreamReader(ctx.Request.Body).ReadToEndAsync();
var obj = JsonSerializer.Deserialize<MeuObjeto>(body);

Você pula completamente o pipeline de Model Binding do ASP.NET Core.

Quanto maior o volume de requests, maior o ganho.


2. Evita re-leitura ou buffering do body

O Model Binding por padrão precisa habilitar buffering para conseguir ler o corpo mais de uma vez, especialmente se filtros, validadores e middlewares precisarem dele.

Quando você lê manualmente:

  • Você controla a leitura
  • Lê apenas uma vez
  • Evita EnableBuffering()
  • Evita overhead de memória (buffer pool)

3. Você pode usar opções otimizadas de JsonSerializer

No binding automático, o ASP.NET usa sempre as opções padrão.

Lendo manualmente você pode:

  • Preconfigurar JsonSerializerOptions
  • Reusar instâncias (menos GC)
  • Usar UTF8 diretamente (sem string intermediária)
  • Desserializar em Stream → objeto sem criar string

Exemplo ultra rápido:

var obj = await JsonSerializer.DeserializeAsync<MeuObjeto>(
ctx.Request.Body,
_options // reusado via DI
);

Isso remove a criação da string inteira → menos alocação e GC.


4. Elimina validações e features que você não usa

Model Binding traz vários comportamentos embutidos:

  • Binding de propriedades complexas
  • Suporte a campos [FromForm], [FromRoute], [FromQuery]
  • Anotações de validação
  • Tratamento de erros no ModelState
  • Conversores default de tipos
  • Handlers de problemas (ProblemDetails)

Se você só quer pegar o JSON e transformar em objeto, tudo isso é desperdício.


5. Menos alocações → menos pressão no GC

Em cenários de centenas de milhares de requisições:

  • Menos objetos
  • Menos strings intermediárias
  • Menos dicionários internos
  • Menos boxing/unboxing em metadata

Reduz drasticamente Gen0 GC, que vira gargalo sob carga.


📌 Quando o ganho é perceptível?

O ganho só aparece em:

  • APIs de altíssima performance
  • Endpoints de alto volume
  • Payloads médios/grandes
  • APIs que não precisam de ModelState ou validações automáticas

Em sistemas internos de alta carga (ex.: microservices high throughput), a diferença chega a 10–40% dependendo do payload.


📊 Resumo em uma linha

👉 Ler o body manualmente via HttpContext é mais rápido porque elimina o custo do Model Binding, reduz alocações e evita passos desnecessários do pipeline do ASP.NET Core.