Escáner de código de barras ASP.NET Core para VeriFactu y AEAT
Cumplimiento fiscal en España: El Real Decreto 1007/2023 y el régimen VeriFactu (Real Decreto-Ley 15/2025) obligan a que toda factura española incluya un código QR que enlace a
sede.agenciatributaria.gob.es. IronBarcode con ASP.NET Core Razor Pages es la solución .NET de referencia para generar y leer estos códigos QR de AEAT en sistemas de facturación web, incluida la integración con el servicio web de TicketBAI para el comercio minorista del País Vasco (Bizkaia, Gipuzkoa y Araba).
Introducción
ASP.NET Core es un marco de trabajo multiplataforma para construir aplicaciones web modernas. Su modelo de Razor Pages ofrece un enfoque basado en páginas para manejar solicitudes HTTP, lo que lo hace ideal para el procesamiento de códigos de barras del lado del servidor. Con IronBarcode, las imágenes cargadas se pueden recibir como objetos IFormFile, convertir en arreglos de bytes y pasar directamente al lector de códigos de barras sin escribir archivos temporales en el disco.
Este artículo guía sobre cómo integrar IronBarcode en una aplicación ASP.NET Core Razor Pages para escanear códigos de barras y códigos QR de imágenes subidas, así como generar códigos de barras desde el servidor.
Cómo leer y escanear códigos de barras en ASP.NET Core
- Instalar la biblioteca C# para leer y escanear códigos de barras
- Crear un nuevo proyecto ASP.NET Core Razor Pages
- Diseñar el formulario de carga de archivos para aceptar imágenes de códigos de barras
- Usar el método
Readpara escanear la imagen cargada en busca de códigos de barras - Mostrar el valor del código de barras decodificado en la página
IronBarcode: Biblioteca de códigos de barras C
IronBarcode proporciona una API robusta para leer y escribir códigos de barras en aplicaciones .NET. La biblioteca maneja el procesamiento de imágenes internamente, por lo que los desarrolladores pueden pasar bytes en bruto, rutas de archivos o flujos directamente al método BarcodeReader.Read sin necesitar bibliotecas de procesamiento de imágenes por separado. Admite una amplia gama de formatos de código de barras, incluidos QR Code, Code 128, Code 39, PDF417, EAN, y muchos otros.
Para aplicaciones web, IronBarcode es particularmente útil porque procesa imágenes completamente en memoria. Los archivos subidos no necesitan guardarse en disco, lo que simplifica la implementación y reduce la sobrecarga de limpieza. La misma biblioteca también genera códigos de barras con BarcodeWriter.CreateBarcode, lo que la convierte en una sola dependencia tanto para lectura como para escritura.
Pasos para construir un escáner de código de barras en ASP.NET Core
Siga estos pasos para crear un escáner de códigos de barras basado en la web usando ASP.NET Core Razor Pages e IronBarcode.
Prerrequisitos
- Visual Studio 2022 o posterior (o cualquier IDE con soporte for .NET)
- .NET 6.0 o SDK posterior
Crear el proyecto
Cree un nuevo proyecto ASP.NET Core Web App (Razor Pages). Esto se puede hacer a través del asistente de proyectos de Visual Studio o desde la línea de comandos:
dotnet new webapp -n BarcodeWebApp
dotnet new webapp -n BarcodeWebApp
Instalar la biblioteca IronBarcode
Instalar la biblioteca IronBarcode usando la consola del Administrador de paquetes NuGet. Navegue a Tools > NuGet Package Manager > Package Manager Console en Visual Studio y ejecute:
Install-Package BarCode
Alternativamente, instálelo desde la línea de comandos con dotnet add package BarCode. La versión más reciente está disponible en el sitio web de NuGet.
Frontend
El frontend consiste en un formulario de carga de archivos y un área de visualización de resultados. El formulario utiliza enctype="multipart/form-data" para manejar cargas de archivos binarios. Cuando se detecta un código de barras, el resultado aparece en una alerta de éxito debajo de la imagen cargada.
Reemplace el contenido en el archivo Index.cshtml con lo siguiente:
@page
@model IndexModel
@{
ViewData["Title"] = "Barcode Scanner";
}
<div class="container mt-4">
<h1 class="mb-4">Barcode Scanner</h1>
<div class="card mb-4">
<div class="card-header"><h5>Upload & Read Barcode</h5></div>
<div class="card-body">
<form method="post" asp-page-handler="Upload" enctype="multipart/form-data">
<div class="mb-3">
<label for="file" class="form-label">Select a barcode image:</label>
<input type="file" class="form-control" id="file"
name="UploadedFile" accept="image/*" />
</div>
<button type="submit" class="btn btn-primary">Scan Barcode</button>
</form>
@if (Model.ImageDataUrl != null)
{
<div class="mt-3">
<h6>Uploaded Image:</h6>
<img src="@Model.ImageDataUrl" alt="Uploaded barcode"
style="max-width: 300px;" class="img-thumbnail" />
</div>
}
@if (Model.BarcodeResult != null)
{
<div class="alert alert-success mt-3">
<strong>Barcode Value:</strong> @Model.BarcodeResult
</div>
}
@if (Model.ErrorMessage != null)
{
<div class="alert alert-warning mt-3">@Model.ErrorMessage</div>
}
</div>
</div>
</div>
@page
@model IndexModel
@{
ViewData["Title"] = "Barcode Scanner";
}
<div class="container mt-4">
<h1 class="mb-4">Barcode Scanner</h1>
<div class="card mb-4">
<div class="card-header"><h5>Upload & Read Barcode</h5></div>
<div class="card-body">
<form method="post" asp-page-handler="Upload" enctype="multipart/form-data">
<div class="mb-3">
<label for="file" class="form-label">Select a barcode image:</label>
<input type="file" class="form-control" id="file"
name="UploadedFile" accept="image/*" />
</div>
<button type="submit" class="btn btn-primary">Scan Barcode</button>
</form>
@if (Model.ImageDataUrl != null)
{
<div class="mt-3">
<h6>Uploaded Image:</h6>
<img src="@Model.ImageDataUrl" alt="Uploaded barcode"
style="max-width: 300px;" class="img-thumbnail" />
</div>
}
@if (Model.BarcodeResult != null)
{
<div class="alert alert-success mt-3">
<strong>Barcode Value:</strong> @Model.BarcodeResult
</div>
}
@if (Model.ErrorMessage != null)
{
<div class="alert alert-warning mt-3">@Model.ErrorMessage</div>
}
</div>
</div>
</div>
El diseño utiliza clases de Bootstrap que ya están incluidas en la plantilla predeterminada de ASP.NET Core. El formulario se envía al manejador de página Upload, y los bloques condicionales muestran la vista previa de la imagen cargada, el resultado decodificado o un mensaje de error.
Ejemplos de códigos de barras de entrada
Los siguientes códigos de barras de muestra pueden usarse para probar el escáner. Cada imagen codifica un formato y un valor diferente:
Código QR que codifica "https://ironsoftware.com"
Codificación de código de barras 128 "IronBarcode-2026"
Código de barras Code 39 que codifica "HELLO123"
Escaneo de códigos de barras con IronBarcode
La lógica del lado del servidor maneja el archivo cargado en el método OnPostUploadAsync. El IFormFile cargado se lee en un arreglo de bytes, que se pasa directamente a BarcodeReader.Read. Esto evita guardar archivos temporales y mantiene el procesamiento completamente en memoria.
Reemplace el contenido en Index.cshtml.cs con:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using IronBarCode;
public class IndexModel : PageModel
{
[BindProperty]
public IFormFile? UploadedFile { get; set; }
public string? BarcodeResult { get; set; }
public string? ErrorMessage { get; set; }
public string? ImageDataUrl { get; set; }
public void OnGet()
{
}
public async Task<IActionResult> OnPostUploadAsync()
{
if (UploadedFile == null || UploadedFile.Length == 0)
{
ErrorMessage = "Please select an image file.";
return Page();
}
try
{
using var ms = new MemoryStream();
await UploadedFile.CopyToAsync(ms);
byte[] imageBytes = ms.ToArray();
// Store image as base64 for preview display
string base64 = Convert.ToBase64String(imageBytes);
ImageDataUrl = $"data:{UploadedFile.ContentType};base64,{base64}";
// Read barcode from uploaded image bytes
var results = BarcodeReader.Read(imageBytes);
if (results != null && results.Count() > 0)
{
BarcodeResult = string.Join("\n",
results.Select(r => r.Value));
}
else
{
ErrorMessage = "No barcode detected in the uploaded image.";
}
}
catch (Exception ex)
{
ErrorMessage = $"Error processing image: {ex.Message}";
}
return Page();
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using IronBarCode;
public class IndexModel : PageModel
{
[BindProperty]
public IFormFile? UploadedFile { get; set; }
public string? BarcodeResult { get; set; }
public string? ErrorMessage { get; set; }
public string? ImageDataUrl { get; set; }
public void OnGet()
{
}
public async Task<IActionResult> OnPostUploadAsync()
{
if (UploadedFile == null || UploadedFile.Length == 0)
{
ErrorMessage = "Please select an image file.";
return Page();
}
try
{
using var ms = new MemoryStream();
await UploadedFile.CopyToAsync(ms);
byte[] imageBytes = ms.ToArray();
// Store image as base64 for preview display
string base64 = Convert.ToBase64String(imageBytes);
ImageDataUrl = $"data:{UploadedFile.ContentType};base64,{base64}";
// Read barcode from uploaded image bytes
var results = BarcodeReader.Read(imageBytes);
if (results != null && results.Count() > 0)
{
BarcodeResult = string.Join("\n",
results.Select(r => r.Value));
}
else
{
ErrorMessage = "No barcode detected in the uploaded image.";
}
}
catch (Exception ex)
{
ErrorMessage = $"Error processing image: {ex.Message}";
}
return Page();
}
}
Imports Microsoft.AspNetCore.Mvc
Imports Microsoft.AspNetCore.Mvc.RazorPages
Imports IronBarCode
Imports System.IO
Imports System.Threading.Tasks
Public Class IndexModel
Inherits PageModel
<BindProperty>
Public Property UploadedFile As IFormFile
Public Property BarcodeResult As String
Public Property ErrorMessage As String
Public Property ImageDataUrl As String
Public Sub OnGet()
End Sub
Public Async Function OnPostUploadAsync() As Task(Of IActionResult)
If UploadedFile Is Nothing OrElse UploadedFile.Length = 0 Then
ErrorMessage = "Please select an image file."
Return Page()
End If
Try
Using ms As New MemoryStream()
Await UploadedFile.CopyToAsync(ms)
Dim imageBytes As Byte() = ms.ToArray()
' Store image as base64 for preview display
Dim base64 As String = Convert.ToBase64String(imageBytes)
ImageDataUrl = $"data:{UploadedFile.ContentType};base64,{base64}"
' Read barcode from uploaded image bytes
Dim results = BarcodeReader.Read(imageBytes)
If results IsNot Nothing AndAlso results.Count() > 0 Then
BarcodeResult = String.Join(vbLf, results.Select(Function(r) r.Value))
Else
ErrorMessage = "No barcode detected in the uploaded image."
End If
End Using
Catch ex As Exception
ErrorMessage = $"Error processing image: {ex.Message}"
End Try
Return Page()
End Function
End Class
Los pasos clave en el código anterior:
- Recibir la carga - El
IFormFileestá vinculado a través de[BindProperty]y se recibe en el manejador POST. - Convertir a bytes - El archivo se copia a un
MemoryStreamy se convierte en un arreglo de bytes. Este es el mismo enfoque utilizado en el ejemplo de escáner web, adaptado paraIFormFileen ASP.NET Core en lugar de cadenas base64. - Leer el código de barras -
BarcodeReader.Read(imageBytes)procesa la imagen y devuelve todos los códigos de barras detectados. - Mostrar el resultado - Todos los valores de códigos de barras detectados se unen y se muestran en la UI.
El siguiente GIF demuestra el lector de códigos de barras en acción, subiendo una imagen de código de barras y mostrando el resultado decodificado:
Lector de códigos de barras escaneando una imagen cargada en la aplicación ASP.NET Core
Procesamiento de datos de imagen Base64
Para aplicaciones que reciben datos de imagen como cadenas base64 (por ejemplo, de capturas de cámara web o lienzos de JavaScript), el mismo método BarcodeReader.Read funciona con arreglos de bytes decodificados de base64. Este patrón es común en aplicaciones de una sola página que envían datos de imagen a través de AJAX:
public string ReadBarCode(string imageDataBase64)
{
// Decode the base64 image data
var splitObject = imageDataBase64.Split(',');
byte[] imageByteData = Convert.FromBase64String(
(splitObject.Length > 1) ? splitObject[1] : splitObject[0]);
// Read barcode directly from byte array
var results = BarcodeReader.Read(imageByteData);
return $"{DateTime.Now}: Barcode is ({results.First().Value})";
}
public string ReadBarCode(string imageDataBase64)
{
// Decode the base64 image data
var splitObject = imageDataBase64.Split(',');
byte[] imageByteData = Convert.FromBase64String(
(splitObject.Length > 1) ? splitObject[1] : splitObject[0]);
// Read barcode directly from byte array
var results = BarcodeReader.Read(imageByteData);
return $"{DateTime.Now}: Barcode is ({results.First().Value})";
}
Public Function ReadBarCode(imageDataBase64 As String) As String
' Decode the base64 image data
Dim splitObject = imageDataBase64.Split(","c)
Dim imageByteData As Byte() = Convert.FromBase64String(
If(splitObject.Length > 1, splitObject(1), splitObject(0)))
' Read barcode directly from byte array
Dim results = BarcodeReader.Read(imageByteData)
Return $"{DateTime.Now}: Barcode is ({results.First().Value})"
End Function
Este enfoque maneja tanto formatos base64 en bruto como URI de datos (por ejemplo, data:image/png;base64,...) dividiendo por la coma y tomando la carga útil base64 real. Para una implementación completa en Blazor usando este patrón, vea la guía de integración de Blazor.
Generación de códigos de barras en el servidor
IronBarcode también puede generar códigos de barras en el servidor. Agregar un punto de generación a la misma aplicación es sencillo con BarcodeWriter.CreateBarcode:
public IActionResult OnPostGenerate()
{
var barcode = BarcodeWriter.CreateBarcode(
"https://ironsoftware.com", BarcodeEncoding.QRCode);
byte[] barcodeBytes = barcode.ToPngBinaryData();
return File(barcodeBytes, "image/png", "generated-barcode.png");
}
public IActionResult OnPostGenerate()
{
var barcode = BarcodeWriter.CreateBarcode(
"https://ironsoftware.com", BarcodeEncoding.QRCode);
byte[] barcodeBytes = barcode.ToPngBinaryData();
return File(barcodeBytes, "image/png", "generated-barcode.png");
}
Public Function OnPostGenerate() As IActionResult
Dim barcode = BarcodeWriter.CreateBarcode("https://ironsoftware.com", BarcodeEncoding.QRCode)
Dim barcodeBytes As Byte() = barcode.ToPngBinaryData()
Return File(barcodeBytes, "image/png", "generated-barcode.png")
End Function
El código de barras generado se devuelve como una descarga de archivo. La siguiente imagen muestra la salida del código QR producida por el manejador OnPostGenerate:
Código QR generado en el servidor con BarcodeWriter.CreateBarcode
Para más opciones de generación de códigos de barras, vea el tutorial de generación de imágenes de códigos de barras y la guía de estilo de códigos de barras.
Ejecución de la aplicación
Ejecute el proyecto desde Visual Studio o la línea de comandos:
dotnet run
dotnet run
La aplicación comienza en el puerto especificado en launchSettings.json (típicamente https://localhost:5001 o similar). Navegue a la página de inicio para ver la interfaz de escáner de códigos de barras.
Integración con el ecosistema de facturación electrónica de España
La combinación de ASP.NET Core Razor Pages e IronBarcode cubre los principales requisitos de códigos de barras del marco fiscal español:
VeriFactu y AEAT QR: El controlador Razor Pages puede recibir imágenes escaneadas de facturas, extraer el código QR de AEAT con BarcodeReader.Read() y decodificar la URL de verificación con el formato https://sede.agenciatributaria.gob.es/Sede/...?nif={NIF}&numserie={SERIE}&fecha={FECHA}&importe={IMPORTE}&huella={HUELLA}. El parámetro huella contiene el hash de la cadena de bloques VeriFactu, cuya presencia acredita la integridad de la factura ante la AEAT. El método OnPostUploadAsync procesa el IFormFile completamente en memoria, sin archivos temporales en disco, lo que facilita el despliegue en entornos cloud como Azure o AWS.
TicketBAI (País Vasco): Los portales web de comercio minorista de Bizkaia, Gipuzkoa y Araba deben integrar el servicio web TicketBAI. El escáner ASP.NET Core lee los códigos QR de los tíquets TicketBAI, extrae el hash de verificación y lo envía al servicio de validación de la Diputación Foral correspondiente. IronBarcode gestiona correctamente los códigos QR de versión 4 o superior requeridos por la longitud de las URL de AEAT.
Facturae y SII: Para la facturación pública electrónica (FACe) y el Suministro Inmediato de Información (SII) a la AEAT, el mismo patrón de lectura en memoria sirve para decodificar los códigos de barras de identificación de facturas Facturae adjuntos a los documentos XML del sector público. Los equipos de desarrollo pueden reutilizar el controlador Razor Pages como punto de entrada de un microservicio de validación de facturas.
Para entornos de producción con alto volumen de facturas, combine las regiones de recorte (BarcodeReaderOptions.CropArea) con el procesamiento asíncrono para procesar lotes de imágenes escaneadas de facturas conforme a los plazos del SII.
Conclusión
Este artículo demostró cómo construir un escáner de código de barras del lado del servidor utilizando ASP.NET Core Razor Pages e IronBarcode. El mismo enfoque funciona con controladores MVC de ASP.NET Core, puntos finales de Web API y aplicaciones de Blazor Server adaptando cómo se reciben los datos de imagen. IronBarcode maneja el procesamiento de imágenes internamente, por lo que la integración requiere un código mínimo sin importar el marco web.
Para leer códigos de barras en otras plataformas .NET, consulte el tutorial de escáner de códigos de barras .NET MAUI y las guías de cómo leer códigos de barras de imágenes. Obtenga más tutoriales sobre IronBarcode en el tutorial de lectura de códigos de barras.
To get started quickly, download the complete BarcodeWebApp project and run it with dotnet run.
IronBarcode debe tener licencia para desarrollo y uso comercial. Los detalles de licencias están disponibles aquí.
Preguntas Frecuentes
¿Cómo puedo implementar un escáner de códigos de barras en ASP.NET Core usando Razor Pages?
Puede usar IronBarcode en su proyecto ASP.NET Core Razor Pages para implementar un escáner de códigos de barras. La biblioteca le permite leer varios formatos de código de barras, como códigos QR, Code 128 y Code 39, cargando imágenes y procesándolas con BarcodeReader.Read.
¿Qué tipos de códigos de barras se pueden leer usando IronBarcode?
IronBarcode soporta la lectura de múltiples formatos de código de barras, incluyendo códigos QR, Code 128 y Code 39, haciéndolo versátil para diversas aplicaciones.
¿Cómo subo imágenes para escanear códigos de barras en un proyecto ASP.NET Core?
En un proyecto ASP.NET Core, puede cargar imágenes utilizando IFormFile. IronBarcode procesa estas imágenes para leer los códigos de barras contenidos en ellas.
¿Puede IronBarcode generar códigos de barras del lado del servidor en ASP.NET Core?
Sí, IronBarcode puede generar códigos de barras del lado del servidor en ASP.NET Core usando el método BarcodeWriter.CreateBarcode, permitiéndole crear y mostrar códigos de barras dinámicamente.
¿Para qué se utiliza el método BarcodeReader.Read?
El método BarcodeReader.Read en IronBarcode se utiliza para decodificar códigos de barras a partir de imágenes, siendo una parte crucial para implementar un escáner de códigos de barras en ASP.NET Core.
¿Es posible escanear tanto códigos QR como códigos de barras usando la misma biblioteca en ASP.NET Core?
Sí, IronBarcode le permite escanear tanto códigos QR como varios otros formatos de código de barras dentro de la misma aplicación ASP.NET Core, proporcionando una solución unificada.
¿Cuáles son los beneficios de usar IronBarcode para el escaneo de códigos de barras en C#?
IronBarcode ofrece fácil integración, soporte para múltiples formatos de código de barras y capacidades robustas de generación de códigos de barras del lado del servidor, lo que lo convierte en una elección eficiente para el escaneo de códigos de barras en aplicaciones C#.
¿Cómo puedo leer el código QR de AEAT de una factura española con ASP.NET Core e IronBarcode?
Cree un controlador Razor Pages que reciba el archivo de imagen mediante IFormFile, copie el flujo a un MemoryStream y páselo a BarcodeReader.Read(). El resultado decodificado contendrá la URL de verificación de AEAT con el formato sede.agenciatributaria.gob.es/Sede/...?nif=...&huella=... que acredita el registro VeriFactu de la factura.
¿IronBarcode es compatible con los requisitos de TicketBAI del País Vasco en aplicaciones web?
Sí. Los portales web de Bizkaia, Gipuzkoa y Araba pueden integrar IronBarcode en ASP.NET Core para leer los códigos QR de los tíquets TicketBAI y extraer el hash de verificación requerido por las Diputaciones Forales del País Vasco.
¿IronBarcode soporta el procesamiento por lotes de códigos de barras?
Sí, IronBarcode admite el procesamiento por lotes, permitiendo a los desarrolladores generar o leer múltiples códigos de barras en una sola operación, mejorando la eficiencia para aplicaciones a gran escala.

