Curl DotNet: Llevando los superpoderes de Curl al tiempo de ejecución de .NET
Para todo desarrollador .NET, el escenario es demasiado familiar: estás leyendo la documentación de una nueva API y el proveedor te da un comando curl para probar un endpoint. Te quedas mirando la sintaxis de la herramienta de línea de comandos, suspiras y comienzas el tedioso proceso de traducirla a una nueva instancia de HttpClient en C#.
Hay que mapear manualmente las cabeceras, asegurarse de que el valor de la cadena para el cuerpo está codificado correctamente, manejar el agente de usuario y esperar no haber pasado por alto un valor por defecto silencioso. Este proceso manual de copia y traducción de bash es propenso a errores. Si falta un encabezado, la solicitud HTTP falla.
Introduzca CurlDotNet. Creada por Jacob Mellor, director de tecnología de Iron Software, esta biblioteca .NET cambia por completo el flujo de trabajo. Le permite pegar comandos curl directamente en su código y ejecutarlos con el mismo comportamiento que espera del terminal.
¿Qué es Curl .NET?
CurlDotNet es una implementación .NET pura de la herramienta CLI curl. A diferencia de otros wrappers, esta biblioteca no tiene dependencias nativas (como libcurl.dll). Se ha creado íntegramente en código gestionado, lo que significa que se ejecuta sin problemas en Windows, Linux y macOS sin necesidad de configuraciones complejas.
Tanto si está trabajando en una aplicación web en .NET Core como en una aplicación de consola o en canalizaciones CI, CurlDotNet aporta la verdadera semántica de Curl al tiempo de ejecución de .NET.
Características clave
Cero Traducción: Pegue los comandos HTTPS de curl directamente en su código fuente de C#.
Multiplataforma: Compatibilidad total con Windows, Linux, MacOS, etc.
Seguridad tipográfica: Opción de utilizar un constructor fluido para escenarios de inyección de dependencias.
- Observabilidad: Soporte incorporado para emitir eventos estructurados para el registro.
Cómo empezar: Instalar y ejecutar
Para empezar, necesita instalar el paquete curldotnet a través de su gestor de paquetes. Puedes encontrar la última versión en las notas de la versión o simplemente ejecutarla:
dotnet add paquete CurlDotNetUna vez instalado, puede ejecutar una llamada curl inmediatamente.
La API de cadenas: Comandos Paste y Go Curl
Este método es perfecto para comprobaciones de estado, agentes de soporte o creación rápida de prototipos. Basta con pasar el comando curl como una cadena.
using CurlDotNet;
// Simply paste the command string
var response = await Curl.ExecuteAsync("curl https://api.github.com/users/octocat");
// Access the data
Console.WriteLine(response.Body);using CurlDotNet;
// Simply paste the command string
var response = await Curl.ExecuteAsync("curl https://api.github.com/users/octocat");
// Access the data
Console.WriteLine(response.Body);Imports CurlDotNet
' Simply paste the command string
Dim response = Await Curl.ExecuteAsync("curl https://api.github.com/users/octocat")
' Access the data
Console.WriteLine(response.Body)Uso de Fluent Builder con variables de entorno
Para aplicaciones de producción en las que sea necesario manejar datos sensibles a través de variables de entorno, o que requieran una arquitectura más limpia, el constructor fluido es ideal. Puede especificar un nombre de cadena para las cabeceras o establecer una ruta de archivo explícitamente.
var response = await Curl.GetAsync("https://api.example.com/data")
.WithHeader("Authorization", "Bearer " + Environment.GetEnvironmentVariable("API_KEY"))
.WithTimeout(TimeSpan.FromSeconds(30))
.ExecuteAsync();var response = await Curl.GetAsync("https://api.example.com/data")
.WithHeader("Authorization", "Bearer " + Environment.GetEnvironmentVariable("API_KEY"))
.WithTimeout(TimeSpan.FromSeconds(30))
.ExecuteAsync();Dim response = Await Curl.GetAsync("https://api.example.com/data") _
.WithHeader("Authorization", "Bearer " & Environment.GetEnvironmentVariable("API_KEY")) _
.WithTimeout(TimeSpan.FromSeconds(30)) _
.ExecuteAsync()La conexión Iron Software: Integraciones del mundo real
CurlDotNet está patrocinado por Iron Software, una empresa dedicada a crear herramientas que resuelven los problemas más difíciles para los desarrolladores. Jacob Mellor creó CurlDotNet con la misma filosofía que impulsa la suite Iron Software: la experiencia del desarrollador es lo primero.
La verdadera potencia de CurlDotNet se despliega cuando se combina con los productos de Iron Software. Puede utilizar Curl para la compleja capa de transporte (gestión de proxies, autenticación heredada o peculiaridades http específicas de Curl) y las bibliotecas Iron para el trabajo pesado de procesamiento de documentos.
Ejemplo 1: Descarga y edición seguras de PDF con IronPDF

IronPDF es el estándar del sector para la generación de archivos PDF perfectos en .NET. A diferencia de otras bibliotecas que tienen problemas con los estándares web modernos, IronPDF renderiza HTML, CSS y JavaScript exactamente como lo haría un navegador Chrome. Está diseñado para ser una solución completa: puedes generar nuevos documentos a partir de cadenas HTML o archivos, editar PDFs existentes, fusionar documentos y aplicar características de seguridad como marca de agua y cifrado sin necesidad de dependencias externas o Adobe Acrobat instalado en el servidor.
Imagine que necesita descargar una factura generada desde un sistema interno heredado que requiere banderas curl complejas (como ignorar errores SSL o permutaciones de encabezado específicas) y, a continuación, marcarla con IronPDF.
Traducir esa petición a HttpClient puede llevar horas de depuración. Con CurlDotNet, se pega el comando, se obtienen los bytes y se entregan a IronPDF.
using CurlDotNet;
using IronPdf;
// 1. Use CurlDotNet to handle the complex transport
// We use -k to allow insecure SSL (common in legacy internal apps)
var curlCommand = "curl -k https://internal-billing.local/invoice/1234 -H 'X-Dept: Sales'";
var response = await Curl.ExecuteAsync(curlCommand);
if (response.IsSuccess)
{
// 2. Pass the raw bytes directly to IronPDF
// IronPDF renders the PDF from the downloaded data
var pdfDocument = PdfDocument.FromPdf(response.BodyBytes);
// 3. Apply a watermark and save
pdfDocument.ApplyWatermark("CONFIDENTIAL", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdfDocument.SaveAs("Processed_Invoice.pdf");
Console.WriteLine("Invoice downloaded and secured via IronPDF.");
}using CurlDotNet;
using IronPdf;
// 1. Use CurlDotNet to handle the complex transport
// We use -k to allow insecure SSL (common in legacy internal apps)
var curlCommand = "curl -k https://internal-billing.local/invoice/1234 -H 'X-Dept: Sales'";
var response = await Curl.ExecuteAsync(curlCommand);
if (response.IsSuccess)
{
// 2. Pass the raw bytes directly to IronPDF
// IronPDF renders the PDF from the downloaded data
var pdfDocument = PdfDocument.FromPdf(response.BodyBytes);
// 3. Apply a watermark and save
pdfDocument.ApplyWatermark("CONFIDENTIAL", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdfDocument.SaveAs("Processed_Invoice.pdf");
Console.WriteLine("Invoice downloaded and secured via IronPDF.");
}Imports CurlDotNet
Imports IronPdf
' 1. Use CurlDotNet to handle the complex transport
' We use -k to allow insecure SSL (common in legacy internal apps)
Dim curlCommand As String = "curl -k https://internal-billing.local/invoice/1234 -H 'X-Dept: Sales'"
Dim response = Await Curl.ExecuteAsync(curlCommand)
If response.IsSuccess Then
' 2. Pass the raw bytes directly to IronPDF
' IronPDF renders the PDF from the downloaded data
Dim pdfDocument = PdfDocument.FromPdf(response.BodyBytes)
' 3. Apply a watermark and save
pdfDocument.ApplyWatermark("CONFIDENTIAL", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)
pdfDocument.SaveAs("Processed_Invoice.pdf")
Console.WriteLine("Invoice downloaded and secured via IronPDF.")
End IfConfirmación de la consola

Resultado PDF

Ejemplo 2: Scraping y OCR con IronOCR

IronOCR es una avanzada biblioteca de reconocimiento óptico de caracteres impulsada por el motor Tesseract 5, afinada específicamente para C# y .NET. Admite más de 127 idiomas y se destaca en la lectura de texto de fuentes imperfectas, como escaneos de baja resolución, imágenes rotadas o fondos ruidosos. Sus funciones de "visión por ordenador" le permiten detectar regiones de texto automáticamente, y puede generar datos no solo como cadenas simples, sino como contenido estructurado (códigos de barras, párrafos, líneas y caracteres) para un análisis en profundidad.
A veces necesitas extraer datos de una imagen alojada en un servidor que bloquea los raspadores estándar de .NET. Puede utilizar CurlDotNet para imitar un agente de usuario de navegador estándar sin esfuerzo y, a continuación, utilizar IronOCR para leer el texto.
using CurlDotNet;
using IronOcr;
// 1. Fetch the image using a specific browser User-Agent to bypass blocks
var imgResponse = await Curl.GetAsync("https://site.com/protected-captcha.png")
.WithUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
.ExecuteAsync();
// 2. Use IronOCR to read text from the file bytes
var ocr = new IronTesseract();
using (var input = new OcrInput())
{
input.AddImage(imgResponse.BodyBytes);
var result = ocr.Read(input);
// 3. Output the extracted string value
Console.WriteLine($"OCR Result: {result.Text}");
}using CurlDotNet;
using IronOcr;
// 1. Fetch the image using a specific browser User-Agent to bypass blocks
var imgResponse = await Curl.GetAsync("https://site.com/protected-captcha.png")
.WithUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
.ExecuteAsync();
// 2. Use IronOCR to read text from the file bytes
var ocr = new IronTesseract();
using (var input = new OcrInput())
{
input.AddImage(imgResponse.BodyBytes);
var result = ocr.Read(input);
// 3. Output the extracted string value
Console.WriteLine($"OCR Result: {result.Text}");
}Imports CurlDotNet
Imports IronOcr
' 1. Fetch the image using a specific browser User-Agent to bypass blocks
Dim imgResponse = Await Curl.GetAsync("https://site.com/protected-captcha.png") _
.WithUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)") _
.ExecuteAsync()
' 2. Use IronOCR to read text from the file bytes
Dim ocr = New IronTesseract()
Using input = New OcrInput()
input.AddImage(imgResponse.BodyBytes)
Dim result = ocr.Read(input)
' 3. Output the extracted string value
Console.WriteLine($"OCR Result: {result.Text}")
End UsingEjemplo de salida deOCR

Ejemplo 3: Gestión de inventario con IronBarcode

IronBarcode es una biblioteca versátil diseñada para leer y escribir prácticamente cualquier formato de código de barras, desde UPCs y EANs estándar hasta códigos QR complejos y etiquetas Data Matrix. Se ha creado para la tolerancia a fallos; La biblioteca incluye filtros automáticos de corrección de imagen que pueden agudizar, potencialmente binarizar y rotar imágenes para detectar códigos de barras incluso si están dañados, inclinados o mal iluminados. Esto lo convierte en una herramienta esencial para aplicaciones de logística, comercio minorista e industria en las que no se dispone de escáneres de hardware.
En este escenario, utilizamos el control de red preciso de CurlDotNet para obtener una etiqueta de una API segura, y el potente motor de lectura de IronBarcode para verificar el contenido al instante.
using CurlDotNet;
using IronBarCode;
class Program
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main(string[] args)
{
// 1. Define the URL
string url = "https://barcodeapi.org/api/128/Shipping-Label-Test-123";
try
{
// Add the session cookie to the request headers
client.DefaultRequestHeaders.Add("Cookie", "session_id=xyz123");
// 2. Download the image data as a Byte Array (Preserves binary integrity)
byte[] imageBytes = await client.GetByteArrayAsync(url);
Console.WriteLine($"Downloaded {imageBytes.Length} bytes.");
// 3. Read the barcode directly from the byte array
var result = BarcodeReader.Read(imageBytes);
foreach (var barcode in result)
{
Console.WriteLine($"Detected Format: {barcode.BarcodeType}");
Console.WriteLine($"Value: {barcode.Value}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}using CurlDotNet;
using IronBarCode;
class Program
{
private static readonly HttpClient client = new HttpClient();
public static async Task Main(string[] args)
{
// 1. Define the URL
string url = "https://barcodeapi.org/api/128/Shipping-Label-Test-123";
try
{
// Add the session cookie to the request headers
client.DefaultRequestHeaders.Add("Cookie", "session_id=xyz123");
// 2. Download the image data as a Byte Array (Preserves binary integrity)
byte[] imageBytes = await client.GetByteArrayAsync(url);
Console.WriteLine($"Downloaded {imageBytes.Length} bytes.");
// 3. Read the barcode directly from the byte array
var result = BarcodeReader.Read(imageBytes);
foreach (var barcode in result)
{
Console.WriteLine($"Detected Format: {barcode.BarcodeType}");
Console.WriteLine($"Value: {barcode.Value}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}Imports CurlDotNet
Imports IronBarCode
Imports System.Net.Http
Module Program
Private ReadOnly client As New HttpClient()
Public Async Function Main(args As String()) As Task
' 1. Define the URL
Dim url As String = "https://barcodeapi.org/api/128/Shipping-Label-Test-123"
Try
' Add the session cookie to the request headers
client.DefaultRequestHeaders.Add("Cookie", "session_id=xyz123")
' 2. Download the image data as a Byte Array (Preserves binary integrity)
Dim imageBytes As Byte() = Await client.GetByteArrayAsync(url)
Console.WriteLine($"Downloaded {imageBytes.Length} bytes.")
' 3. Read the barcode directly from the byte array
Dim result = BarcodeReader.Read(imageBytes)
For Each barcode In result
Console.WriteLine($"Detected Format: {barcode.BarcodeType}")
Console.WriteLine($"Value: {barcode.Value}")
Next
Catch ex As Exception
Console.WriteLine($"Error: {ex.Message}")
End Try
End Function
End ModuleSalida de consola de IronBarcode

Llevando "Userland" a .NET
El concepto de "Userland" que CurlDotNet lleva a .NET va más allá de realizar solicitudes. Permite utilizar la funcionalidad estándar de curl en lugares como CI pipelines o contenedores docker ejecutando Linux macOS o windows.
Puedes usarlo para descargar archivos, subir datos, o activar webhooks usando la sintaxis estándar de bash dentro de un contexto de ejecución .NET. De este modo se tiende un puente entre el mundo de las herramientas de línea de comandos y su aplicación compilada.
Conclusión: El fin del impuesto a la traducción
No se trata sólo de hacer peticiones HTTP; se trata de respetar el tiempo del desarrollador. Jacob Mellor y Iron Software entienden que si una herramienta como curl ha funcionado perfectamente durante 25 años, el tiempo de ejecución de .NET debe adoptarla, no obligarte a reimplementarla.
Al adoptar CurlDotNet, no solo está añadiendo una dependencia; estás adoptando un flujo de trabajo que da prioridad al envío de funciones frente a la redacción de textos repetitivos. Deje de "traducir" y empiece a ejecutar. Ya sea que estés obteniendo un solo archivo JSON o orquestando flujos de trabajo complejos de documentos de Iron Software, la instrucción sigue siendo la misma: pegar, ejecutar, listo.
Próximos pasos
Deje de perder tiempo traduciendo cabeceras y depurando HttpClient. Únete al movimiento Userland.NET.
Revisar el GitHub: Visita jacob-mellor/curl-.NET para ver el código fuente, documentación y directorio de ejemplos.
Descargar el paquete NuGet: Ejecuta .NET add package CurlDotNet para instalar la biblioteca.
- Explorar Iron Software: Descubre cómo IronPDF y IronOCR pueden trabajar en conjunto con CurlDotNet para acelerar tu proyecto.
Con CurlDotNet, se asegurará de que sus comandos Curl y su código C# hablen exactamente el mismo idioma.
