How to Import CSV Files in a ASP.NET Core App
How to Import CSV Files into an ASP.NET Core App (Using CSVBox)
Importing CSV files is a common requirement for SaaS apps, internal tools, and enterprise dashboards. This guide shows a practical, developer-focused integration pattern for ASP.NET Core using CSVBox — a hosted CSV uploader and validation service that delivers parsed data to your server via webhooks.
If you maintain a multi-tenant SaaS product or internal admin UI, this walkthrough explains the end-to-end flow (file → map → validate → submit), how to receive and verify webhook payloads in ASP.NET Core, and how to persist rows safely. Updated to be relevant in 2026 with small best-practice notes where useful.
Why use a CSV import tool in ASP.NET Core?
Building a robust CSV import pipeline yourself requires handling multiple concerns:
- File upload UI and client-side validation
- Column mapping between spreadsheet headers and your domain model
- Row-level validation, error reporting, and retry strategies
- Secure delivery and verification of imported data
- CSV parsing edge cases (encodings, quoted fields, malformed rows)
CSVBox offloads the UI and parsing work so you can focus on business logic. Typical benefits include:
- Secure drag-and-drop uploader with mapping and preview
- Client-side validations (required, regex, formats) and per-row feedback
- CSV-to-JSON conversion and webhook delivery to your server
- Dashboard for retries, error inspection, and upload history
This pattern speeds development and improves user experience while keeping server-side control over persistence and business rules.
Typical CSV import flow
- User uploads a CSV file in the browser.
- CSVBox parses the file, shows mapping and validation errors to the user.
- Validated rows are POSTed to your webhook as structured JSON.
- Your ASP.NET Core endpoint verifies the request, applies server-side validation, and persists records.
- You track status and report back to users from your app or via dashboard.
Step-by-step: integrate CSVBox into ASP.NET Core
1. Sign up for CSVBox and create a widget
- Create an account at csvbox.io and add a new import widget in the dashboard.
- Define expected fields (for example: name, email, phone) and set validation rules (required, regex, unique).
- Optionally configure field mapping and preview options so users can map spreadsheet columns to your schema.
- Copy the widget key from the dashboard — you’ll use it in the frontend embed.
2. Create or prepare your ASP.NET Core project
If you do not already have a project:
dotnet new webapp -n CsvImportApp
cd CsvImportApp
Aim to run on a supported runtime (ASP.NET Core 3.1+). For production and long-term support in 2026, consider targeting .NET 6 or newer (LTS) where available.
Ensure JSON body parsing is enabled (System.Text.Json is the default in modern ASP.NET Core apps).
3. Add a webhook endpoint to receive CSV data
CSVBox delivers parsed rows to your server as JSON. Use a minimal, robust controller action that:
- Reads the raw request body when you need to verify a signature
- Validates or maps fields server-side
- Persists records in a transactional way
Example controller using System.Text.Json and a simple signature verification pattern (see CSVBox docs for exact signature algorithm and header name):
// Controllers/CsvImportController.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
[ApiController]
[Route("api/[controller]")]
public class CsvImportController : ControllerBase
{
private readonly IConfiguration _config;
public CsvImportController(IConfiguration config)
{
_config = config;
}
[HttpPost("csvbox-webhook")]
public async Task<IActionResult> ReceiveCsvRecords()
{
// If you will verify signatures, buffer the request body
Request.EnableBuffering();
// Read raw body (needed for signature verification)
string rawBody;
using (var reader = new StreamReader(Request.Body, Encoding.UTF8, leaveOpen: true))
{
rawBody = await reader.ReadToEndAsync();
Request.Body.Position = 0;
}
// Optional: verify webhook signature (see CSVBox docs for algorithm/header name)
var signature = Request.Headers["X-Csvbox-Signature"].ToString();
var secret = _config["Csvbox:WebhookSecret"]; // store secret in configuration or a secrets store
if (!string.IsNullOrEmpty(secret) && !VerifySignature(rawBody, signature, secret))
{
return Unauthorized();
}
// Parse JSON payload
using var doc = JsonDocument.Parse(rawBody);
if (!doc.RootElement.TryGetProperty("data", out var data) ||
!data.TryGetProperty("records", out var records))
{
return BadRequest("Invalid payload: missing data.records");
}
foreach (var record in records.EnumerateArray())
{
var name = record.GetProperty("name").GetString();
var email = record.TryGetProperty("email", out var e) ? e.GetString() : null;
// Apply server-side validation and persist
// Example: map to your EF Core entity, check duplicates, use transactions
}
return Ok();
}
private static bool VerifySignature(string payload, string signatureHeader, string secret)
{
if (string.IsNullOrEmpty(signatureHeader) || string.IsNullOrEmpty(secret))
return false;
// Example HMAC-SHA256 verification producing a hex string.
// Confirm exact algorithm and header format in the CSVBox webhook docs.
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var expectedHex = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
return signatureHeader.Equals(expectedHex, StringComparison.OrdinalIgnoreCase);
}
}
Notes:
- Replace verification logic with the exact algorithm and header format documented by CSVBox (see the official webhook security docs).
- Keep secrets (webhook secret) in environment variables or a secrets store, not in source code.
- Persist records inside a database transaction and return a suitable HTTP status to allow CSVBox retries on failure.
4. Embed the CSVBox widget in a Razor Page
Add the CSVBox widget script and initialize it with your widget key. Keep UI-level validation and mapping in CSVBox so the server receives clean, structured JSON.
<!-- Pages/Upload.cshtml -->
@page
@model UploadModel
@section Scripts {
<script src="https://js.csvbox.io/widget.js"></script>
<script>
// Replace with your widget key from the dashboard
const widgetKey = "your_widget_key_here";
const csvbox = new CSVBoxWidget({
widgetKey: widgetKey,
user: {
id: "user_id", // optional: identify the uploader session
email: "user@example.com"
},
onUploadComplete: function(result) {
console.log("Upload complete:", result);
// result usually contains upload_id, status and any per-row error summaries
// you can call your backend to link upload_id with user records
},
onError: function(err) {
console.error("CSVBox widget error:", err);
}
});
csvbox.mount("#csvbox-uploader");
</script>
}
<h2>Upload Your CSV File</h2>
<div id="csvbox-uploader"></div>
Replace the widget key and optionally pass user/session information for traceability. Consult your CSVBox dashboard settings for widget customization (labels, required fields, preview behavior).
Sample webhook payload format
A typical CSVBox webhook payload contains an event and structured data. Confirm exact fields with the CSVBox docs, but a common shape looks like:
{
"event": "upload.completed",
"data": {
"records": [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
],
"upload_id": "abc123"
}
}
This lets your server iterate records and persist them. You can also use upload_id to reconcile items in your dashboard or show progress to users.
Webhook security (recommended)
CSVBox supports signing webhook requests so your endpoint can validate authenticity. General best practices:
- Configure a per-widget or per-project webhook secret in the CSVBox dashboard.
- Verify the signature header on every inbound request before processing payloads.
- Use constant-time comparison when comparing signatures.
- Return 401/403 for invalid signatures; return 200 only after successful processing.
- Store secrets in a secure store or environment variable, not in code.
Read the CSVBox webhook security docs for the exact header name and HMAC algorithm to implement on your server: https://help.csvbox.io/developer-guide/6.-webhooks#security
Common issues and fixes
| Problem | Solution |
|---|---|
| No data received in webhook | Ensure your endpoint is publicly accessible and reachable by CSVBox. Confirm the webhook URL in the CSVBox dashboard and that the endpoint accepts POST requests. |
| 500 error on upload | Inspect server logs for JSON parsing errors or null reference exceptions. Verify payload shape against your model. Use defensive parsing (TryGetProperty) and return clear errors for retries. |
| JavaScript widget doesn’t render | Confirm the widget script URL is included, the mount selector exists, and the widget key is valid. Check the browser console for network errors. |
| Need to test locally | Use a tunneling tool like ngrok to expose your local endpoint and update the webhook URL for testing. |
| Duplicate or partial imports | Apply idempotency on upload_id or a unique row identifier to avoid duplicate creation on retries. Use database transactions to ensure consistency. |
Why this approach helps shipping faster in 2026
By delegating parsing, UI, and immediate validation to CSVBox, your team spends less time on edge cases and more on domain logic: mapping rows to models, enforcing business rules, and creating reliable persistence. This is particularly valuable for SaaS teams that need reliable bulk imports and clear user feedback without maintaining upload UX and CSV parsers in-house.
What you’ve learned
- How CSVBox fits into an ASP.NET Core import flow: file → map → validate → submit.
- How to receive webhook payloads and implement basic signature verification.
- Best practices for server-side validation, idempotency, and persistence.
- Practical tips for testing locally and troubleshooting webhook issues.
Next steps:
- Add user-level authentication and link uploads to accounts.
- Persist parsed records with server-side validation and idempotency keys.
- Customize widget appearance and field labels in the CSVBox dashboard.
- Monitor uploads and errors through the CSVBox dashboard and your app.
Useful resources
- Getting started with CSVBox: https://help.csvbox.io/getting-started/2.-install-code
- Securing webhooks with HMAC (CSVBox docs): https://help.csvbox.io/developer-guide/6.-webhooks#security
- ASP.NET Core documentation: https://learn.microsoft.com/aspnet/core/
📎 Canonical Reference: ASP.NET Core Integration Guide on CSVBox — https://help.csvbox.io/integrations/asp-net-core-guide