IRONSOFTWAREHOME
USING IRONBARCODE

ASP.NET Barcode Scanner: File Upload and REST API with IronBarcode

Curtis Chau
Curtis Chau
Updated: August 1, 2026

Barcode scanning in ASP.NET becomes straightforward with IronBarcode: install via NuGet, call BarcodeReader.Read(), and get decoded values with type, confidence, and position data in one step -- no complex configuration required.

Barcode scanning is a standard requirement in modern web applications, powering inventory management, document processing, and ticket validation workflows. According to GS1, barcodes are used in over 6 billion transactions daily worldwide -- a figure that underscores how critical accurate barcode reading is for any business system. The ISO/IEC 15415 standard defines quality metrics for 2D barcode symbols, while the ISO/IEC 15416 standard covers 1D linear barcodes, both of which IronBarcode supports natively.

This guide shows you how to add reliable barcode scanning to your ASP.NET Core application using IronBarcode, covering installation, file upload processing, REST API integration, and production deployment patterns. By the end, you will have working code for both a Razor page file-upload scanner and a JSON API endpoint that accepts base64-encoded images from any client.

How Do You Install IronBarcode in an ASP.NET Project?

Getting started takes only a few minutes. The library supports both ASP.NET Core and traditional ASP.NET MVC applications, making it adaptable for various project types. Enterprise deployments work equally well on Azure, AWS Lambda, and Docker containers. The library's machine learning-powered detection handles challenging barcode images by applying sophisticated image correction automatically, which is particularly useful when processing photos taken with mobile cameras in variable lighting conditions.

Installing via NuGet Package Manager

Open the Package Manager Console in Visual Studio and run:

PM > Install-Package BarCode

Alternatively, use the .NET CLI:

dotnet add package BarCode

Or search for "BarCode" in the Visual Studio NuGet Package Manager UI and click Install. The package automatically manages all dependencies.

For platform-specific deployments, consider using platform-specific NuGet packages that are optimized for your target environment. The library offers both standard and BarCode.Slim packages to suit different deployment scenarios. For the complete installation walkthrough, see the IronBarcode installation guide.

Configuring Your Project

Once installed, add the necessary using statement to your C# files:

using IronBarCode;

This import gives you access to IronBarcode's complete barcode reading and generation capabilities. The library supports over 30 barcode formats, including QR Code, Code 128, Code 39, Data Matrix, and PDF417. View the complete list of supported barcode formats to confirm compatibility with your use case.

For troubleshooting installation issues, consult the NuGet packages troubleshooting guide or submit an engineering request for specialized support.

Choosing the Right Architecture Pattern

When implementing barcode scanning in ASP.NET, you have two primary architectural approaches. Understanding these patterns helps you choose the right barcode reader settings for each use case:

// Server-side processing -- recommended for most ASP.NET scenarios
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = true,
    UseConfidenceThreshold = true,
    ConfidenceThreshold = 0.85
};

var results = BarcodeReader.Read(stream, options);

foreach (var barcode in results)
{
    Console.WriteLine($"Type: {barcode.BarcodeType}, Value: {barcode.Text}");
}

The server-side approach gives you maximum control over image processing and works consistently across all browsers. When the server processes every image, you also get a clean audit trail: every barcode scanned passes through your application layer where you can log it, validate it against a database, or trigger downstream workflows. This pattern is particularly well-suited for regulated industries like healthcare, logistics, and manufacturing where every scan must be recorded.

For client-side camera capture integration, modern browsers support the MediaDevices API for camera access, which can be combined with IronBarcode's server-side processing through a REST API -- covered in detail later in this guide. Choosing server-side processing also simplifies your security model: there is no sensitive processing logic exposed to the browser, and all validation happens behind your application boundary.

Client-Side vs. Server-Side Barcode Scanning Trade-offs
AspectClient-Side Capture + Server ProcessingPure Server-Side Processing
Best forReal-time scanning with cameraBatch processing, file uploads
Browser supportModern browsers onlyAll browsers
User experienceInstant feedbackStandard upload flow
Security modelMore complex (CORS, auth)Straightforward
Bandwidth usageLower (pre-processed on device)Higher (raw image upload)

How Do You Implement File Upload Barcode Scanning?

File upload scanning is the most common barcode scenario in ASP.NET web applications. This pattern works for processing invoices, shipping labels, or any document with embedded barcodes. For improved throughput, consider implementing asynchronous barcode reading to handle multiple uploads simultaneously.

Building the Upload Form

Create a responsive HTML form in your ASP.NET view:

@* Razor view -- barcode upload form *@
<form method="post" enctype="multipart/form-data" id="barcodeForm">
    <div class="form-group">
        <label for="barcodeFile">Select Barcode Image:</label>
        <input type="file" name="barcodeFile" id="barcodeFile"
               accept="image/*,.pdf" class="form-control"
               capture="environment" />
    </div>
    <button type="submit" class="btn btn-primary" id="scanBtn">
        <span class="spinner-border spinner-border-sm d-none" role="status"></span>
        Scan Barcode
    </button>
</form>
<div id="results">
    @ViewBag.BarcodeResult
</div>

The capture="environment" attribute activates the rear camera on mobile devices, giving users a native camera-like experience without JavaScript.

Implementing Secure Backend Processing

The controller action handles file validation, memory stream processing, and result formatting:

[HttpPost]
[ValidateAntiForgeryToken]
[RequestSizeLimit(10_000_000)] // 10MB limit
public async Task<IActionResult> ScanBarcode(IFormFile barcodeFile)
{
    var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif",
                                    ".tiff", ".bmp", ".pdf" };
    var extension = Path.GetExtension(barcodeFile.FileName).ToLowerInvariant();

    if (!allowedExtensions.Contains(extension))
    {
        ModelState.AddModelError("", "Invalid file type");
        return View();
    }

    if (barcodeFile != null && barcodeFile.Length > 0)
    {
        using var stream = new MemoryStream();
        await barcodeFile.CopyToAsync(stream);
        stream.Position = 0;

        var options = new BarcodeReaderOptions
        {
            Speed = ReadingSpeed.Balanced,
            ExpectMultipleBarcodes = true,
            ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional |
                                BarcodeEncoding.QRCode |
                                BarcodeEncoding.DataMatrix,
            ImageFilters = new ImageFilterCollection
            {
                new SharpenFilter(),
                new ContrastFilter()
            }
        };

        var results = BarcodeReader.Read(stream, options);

        ViewBag.BarcodeResult = results.Any()
            ? string.Join("<br/>", results.Select(r => $"<strong>{r.BarcodeType}:</strong> {r.Text}"))
            : "No barcodes found in the image.";
    }

    return View();
}

This implementation validates file type before processing, reads barcodes from a memory stream, and returns all detected results. IronBarcode processes various image formats, including multipage TIFF and GIF and PDF documents, eliminating format-specific handling code.

What the Scanned Input and Output Look Like

Code 128 barcode encoding URL 'https://ironsoftware.com/csharp/barcode/' displaying machine-readable bars with human-readable text below for accurate scanning in ASP.NET barcode reader applications

The example above shows a standard Code 128 barcode -- a common format in shipping and inventory applications. After scanning, the result screen confirms the decoded value along with confidence metadata:

ASP.NET Core web application interface displaying successful barcode scan results with file upload form showing decoded Code128 barcode value and confidence score metadata

IronBarcode returns the barcode type, decoded value, confidence score, and position data for each barcode detected in the uploaded image.

How Do You Build a REST API for Barcode Scanning?

Modern ASP.NET applications often expose barcode scanning capabilities through REST APIs, allowing integration with mobile apps, single-page applications, or third-party services. This pattern supports client-side camera capture with server-side processing.

Security Considerations for Barcode APIs

Before writing the controller, plan the security layer. Barcode data can contain arbitrary content, so always validate inputs. Follow the IronBarcode security guidelines for complete protection:

  • Input validation: Sanitize barcode content before storing or acting on it
  • Rate limiting: Use ASP.NET Core's built-in rate limiting middleware to prevent API abuse
  • Authentication: Secure endpoints with JWT tokens or API keys
  • HTTPS enforcement: All barcode API traffic must travel over TLS
  • CORS policy: Restrict which origins can call your scanning endpoint
  • License key management: Apply license keys correctly and configure them in web.config for production

Building the Production API Controller

[ApiController]
[Route("api/[controller]")]
public class BarcodeController : ControllerBase
{
    private readonly ILogger<BarcodeController> _logger;
    private readonly IMemoryCache _cache;

    public BarcodeController(ILogger<BarcodeController> logger, IMemoryCache cache)
    {
        _logger = logger;
        _cache = cache;
    }

    [HttpPost("scan")]
    [ProducesResponseType(typeof(BarcodeResponse), 200)]
    [ProducesResponseType(typeof(ErrorResponse), 400)]
    public async Task<IActionResult> ScanBarcode([FromBody] BarcodeRequest request)
    {
        try
        {
            if (string.IsNullOrEmpty(request.ImageBase64))
                return BadRequest(new ErrorResponse { Error = "Image data is required" });

            var cacheKey = $"barcode_{request.ImageBase64.GetHashCode()}";
            if (_cache.TryGetValue(cacheKey, out BarcodeResponse cachedResult))
                return Ok(cachedResult);

            byte[] imageBytes = Convert.FromBase64String(request.ImageBase64);

            if (imageBytes.Length > 10 * 1024 * 1024)
                return BadRequest(new ErrorResponse { Error = "Image size exceeds 10MB limit" });

            var options = new BarcodeReaderOptions
            {
                Speed = ReadingSpeed.Faster,
                ExpectMultipleBarcodes = request.ExpectMultiple ?? false,
                UseConfidenceThreshold = true,
                ConfidenceThreshold = 0.8
            };

            var results = await Task.Run(() => BarcodeReader.Read(imageBytes, options));

            var response = new BarcodeResponse
            {
                Success = true,
                Barcodes = results.Select(r => new BarcodeData
                {
                    Type = r.BarcodeType.ToString(),
                    Value = r.Text,
                    Confidence = r.Confidence,
                    Position = new BarcodePosition
                    {
                        X = r.Points.Select(p => p.X).Min(),
                        Y = r.Points.Select(p => p.Y).Min(),
                        Width = r.Width,
                        Height = r.Height
                    }
                }).ToList()
            };

            _cache.Set(cacheKey, response, TimeSpan.FromMinutes(5));
            return Ok(response);
        }
        catch (FormatException)
        {
            return BadRequest(new ErrorResponse { Error = "Invalid base64 image data" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing barcode scan");
            return StatusCode(500, new ErrorResponse { Error = "Internal server error" });
        }
    }
}

public record BarcodeRequest(string ImageBase64, bool? ExpectMultiple);

public record BarcodeResponse
{
    public bool Success { get; init; }
    public List<BarcodeData> Barcodes { get; init; } = new();
}

public record BarcodeData
{
    public string Type { get; init; }
    public string Value { get; init; }
    public double Confidence { get; init; }
    public BarcodePosition Position { get; init; }
}

public record BarcodePosition(int X, int Y, int Width, int Height);

public record ErrorResponse
{
    public bool Success => false;
    public string Error { get; init; }
}

This endpoint accepts base64-encoded images -- the standard format for transmitting images over HTTP. The response includes barcode type, decoded value, confidence score, and position. For high-volume scenarios, review batch barcode processing and reading speed optimization options.

How Does the API Handle Multiple Barcodes?

Three different barcode formats labeled A B C demonstrating QR Code Code128 and DataMatrix symbologies that IronBarcode processes simultaneously in production environments

IronBarcode processes multiple barcodes in a single image in one call, returning an array of results. Each entry in the response includes position data so the client application can highlight detected barcodes on screen.

Browser developer tools network tab showing successful JSON API response containing array of three detected barcodes with complete metadata including type value confidence and position coordinates

The structured JSON response gives client applications everything needed to process and display barcode results without additional lookups.

How Do You Handle Challenging Barcode Images?

Real-world barcode scanning frequently involves imperfect images -- photos taken at angles, poor lighting, or partially damaged barcodes. IronBarcode addresses these scenarios through its advanced image processing capabilities and machine learning confidence thresholds.

Diagnosing Common Scanning Problems

Before applying corrections, identify which category your problem falls into. Most scanning failures in production fall into one of five groups: image quality issues (blur, noise, low resolution), geometric issues (rotation, skew, perspective distortion), damage issues (torn labels, smudged ink), environment issues (glare, shadows, inconsistent lighting), and false positive detection where the reader finds a barcode that does not exist.

Knowing the category helps you select the right filter combination and reading speed without running unnecessary processing on every image. For most web application scenarios, starting with ReadingSpeed.Balanced and AutoRotate = true covers the majority of cases. Only escalate to ExtremeDetail when the first pass returns no results.

The multi-pass approach in the code below implements this tiered strategy. The fast first pass handles typical images quickly, keeping median latency low for the common case. The detailed second pass is only triggered when the first pass fails, ensuring that you pay the extra processing cost only when it is actually needed. This pattern keeps your ASP.NET endpoint responsive under normal load while still handling difficult edge cases reliably.

Common Barcode Scanning Problems and Solutions
ProblemSymptomSolution
Blurry imageLow confidence scores, missed readsApply SharpenFilter, increase ExtremeDetail speed
Rotated barcodeBarcode not detected at allEnable AutoRotate = true
Damaged barcodePartial reads, incorrect valuesEnable error correction, use RemoveFalsePositive
Poor contrastInconsistent detectionApply ContrastFilter and BrightnessFilter
Performance too slowHigh latency on uploadsUse ReadingSpeed.Faster, enable multithreading

Implementing Multi-Pass Image Processing

For challenging images, a tiered processing approach yields the best results without sacrificing performance on easy images:

public class AdvancedBarcodeProcessor
{
    private readonly ILogger<AdvancedBarcodeProcessor> _logger;

    public async Task<List<ScannedBarcode>> ProcessChallengingImage(Stream imageStream)
    {
        // First pass -- fast, minimal processing
        var fastOptions = new BarcodeReaderOptions
        {
            Speed = ReadingSpeed.Balanced,
            ExpectMultipleBarcodes = true,
            AutoRotate = false,
            UseConfidenceThreshold = true,
            ConfidenceThreshold = 0.85
        };

        var results = BarcodeReader.Read(imageStream, fastOptions);

        if (!results.Any())
        {
            // Second pass -- aggressive image correction
            imageStream.Position = 0;

            var detailedOptions = new BarcodeReaderOptions
            {
                Speed = ReadingSpeed.ExtremeDetail,
                ExpectMultipleBarcodes = true,
                AutoRotate = true,
                RemoveFalsePositive = true,
                UseConfidenceThreshold = true,
                ConfidenceThreshold = 0.6,
                Multithreaded = true,
                ExpectBarcodeTypes = BarcodeEncoding.All,
                ImageFilters = new ImageFilterCollection
                {
                    new SharpenFilter(2.5f),
                    new ContrastFilter(2.0f),
                    new BrightnessFilter(1.2f),
                    new InvertFilter()
                }
            };

            results = BarcodeReader.Read(imageStream, detailedOptions);
            _logger.LogInformation("Second pass detected {Count} barcodes", results.Count());
        }

        return results.Select(r => new ScannedBarcode
        {
            Value = r.Text,
            BarcodeType = r.BarcodeType.ToString(),
            Confidence = r.Confidence,
            RotationAngle = r.RotationAngle,
            PageNumber = r.PageNumber
        }).ToList();
    }
}

public record ScannedBarcode
{
    public string Value { get; init; }
    public string BarcodeType { get; init; }
    public double Confidence { get; init; }
    public float RotationAngle { get; init; }
    public int PageNumber { get; init; }
}

The BarcodeReaderOptions class provides fine-grained control over every aspect of scanning. Setting AutoRotate handles images captured at any angle, while image filters improve clarity for blurry or low-contrast barcodes. For detailed configuration, see the barcode reader settings example and PDF-specific reader settings.

When working with PDFs, consider stamping barcodes onto PDFs or creating barcodes as PDF documents. For high-volume processing, enabling multithreading via the async and multithread capabilities significantly improves throughput.

Adding Browser Compatibility and Fallback Strategies

Supporting diverse browsers requires progressive enhancement. Modern browsers on Android and desktop Chrome, Edge, and Firefox support the MediaDevices.getUserMedia() API for camera access. Safari on iOS supports it from version 11 onward. Older enterprise browsers, IE11 compatibility modes, and certain locked-down corporate environments may not support camera access at all, so your fallback file-upload path must always remain functional.

The recommended approach is to use feature detection at runtime rather than user-agent sniffing, then show or hide the camera interface accordingly. Start with a camera-capable interface and fall back gracefully to file upload:

@* Razor view with progressive enhancement *@
<div class="barcode-scanner-container">
    @* Camera capture -- hidden until JavaScript confirms support *@
    <div id="cameraSection" class="d-none">
        <video id="videoPreview" class="w-100" autoplay></video>
        <button id="captureBtn" class="btn btn-primary mt-2">Capture and Scan</button>
    </div>

    @* File upload -- always available as fallback *@
    <div id="uploadSection">
        <form method="post" enctype="multipart/form-data"
              asp-action="ScanBarcode" asp-controller="Barcode">
            <div class="form-group">
                <label>Upload Barcode Image:</label>
                <input type="file" name="file" accept="image/*,.pdf"
                       class="form-control" required />
            </div>
            <button type="submit" class="btn btn-primary">Upload and Scan</button>
        </form>
    </div>
</div>

The Blazor integration provides modern web application support with minimal configuration if you prefer a component-based approach. For deployment troubleshooting, consult the runtimes copy exception guide.

What Are Your Next Steps?

Barcode scanning in ASP.NET is straightforward with IronBarcode. You install one NuGet package, call BarcodeReader.Read(), and get reliable decoded results across 30+ formats -- including challenging real-world images that other libraries struggle with.

To continue building on this foundation, explore these resources:

Start with a free trial license to test IronBarcode in your ASP.NET application with no restrictions. The trial includes full access to all features including multi-format detection, image correction, and the REST API patterns shown in this guide -- so you can evaluate performance on your own images before committing to a production license. For .NET MAUI mobile apps that need on-device scanning, see the .NET MAUI barcode scanner tutorial which extends the same API to iOS and Android targets.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...
Read More

Related Articles

Key in blue circle

Get your free 30-day Trial Key instantly.

Your trial license will be sent to your email address

No limitations. 100% unlocked. No credit card.

bullet_checkedNo credit card or account creation requiredNo limitations. 100% unlocked. No credit card.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Book your free Live Demo
Booking Badge

Trusted by Millions of Engineers Worldwide

Iron Software's customer logos
Get Your No-Obligation Consult
Complete the form below or email sales@ironsoftware.com
Your details will always be kept confidential.
Trusted by Millions of Engineers Worldwide
Iron Software's customer logos
Get your free 30-day Trial Key instantly.
No credit card or account creation required