Developers & agents
Generate a QR code in C#
QRCoder is the .NET standard: CreateQrCode(text, ECCLevel.Q) then PngByteQRCode.GetGraphic(20) returns PNG bytes with no System.Drawing dependency, so it runs on Linux containers. Expose it as an ASP.NET minimal API endpoint, or fetch the keyless API with HttpClient and Uri.EscapeDataString.
QRCoder
dotnet add package QRCoder and the whole flow is generator → data → renderer:
using QRCoder;
using var generator = new QRCodeGenerator();
var qrData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.Q);
byte[] png = new PngByteQRCode(qrData).GetGraphic(20);
File.WriteAllBytes("qr.png", png);
Two details that save real debugging time:
- Use
PngByteQRCode, not the legacyQRCodeclass. The legacy renderer draws through System.Drawing, which is Windows-only on modern .NET — it throws at runtime on Linux containers.PngByteQRCodewrites the PNG itself and runs everywhere. GetGraphic(20)is pixels per module, not total size. A version 2 code (25 modules plus the quiet zone) at 20 px/module lands around 660 px.
ECCLevel.L/M/Q/H are the standard
error-correction levels. For print, use
SvgQRCode from the same package — it returns an SVG string, and
vector is what print needs.
An ASP.NET endpoint
Minimal API version — generation is fast enough to do per-request, and the cache header makes repeats free:
app.MapGet("/qr", (string data) =>
{
using var generator = new QRCodeGenerator();
var qrData = generator.CreateQrCode(data, QRCodeGenerator.ECCLevel.M);
return Results.Bytes(new PngByteQRCode(qrData).GetGraphic(16), "image/png");
});
Add Cache-Control: public, max-age=31536000, immutable if the mapping from input to
image never changes — which for a QR code it does not.
The zero-dependency route: HttpClient
For styled codes (colours, module and eye shapes) or typed, validated payloads
(/api/v1/wifi, /api/v1/upi, /api/v1/vcard), skip the package and call the
keyless API:
using var http = new HttpClient();
var target = "https://example.com/sale?src=poster";
var url = $"https://useqr.app/api/v1/qr?data={Uri.EscapeDataString(target)}&size=1024";
await File.WriteAllBytesAsync("qr.png", await http.GetByteArrayAsync(url));
Uri.EscapeDataString is the load-bearing call — an unescaped & in the payload starts a
new query parameter and truncates the data silently. Keep credentials (WiFi passwords,
personal data) out of any remote call; generate those locally with QRCoder.
Verify styled output
Decode what you encode before it ships:
using System.Net.Http.Json;
var report = await http.GetFromJsonAsync<VerifyReport>(
$"https://useqr.app/api/v1/verify?data={Uri.EscapeDataString(target)}&color=6366f1");
if (report is not { Scannable: true })
throw new InvalidOperationException(string.Join("; ", report!.Issues));
record VerifyReport(bool Scannable, string[] Issues);
The endpoint renders, rasterises and reads the code back with a real decoder — the decode-verify loop in one GET. How QRCoder sits next to ZXing and friends is covered in QR code libraries compared; the JVM equivalent of this page is Java.
FAQ
What is the best C# library for QR codes?
QRCoder. Use its PngByteQRCode renderer, which has no System.Drawing dependency and therefore works on Linux and in containers.
Why does my QRCoder code crash on Linux?
You are using the legacy QRCode renderer, which needs System.Drawing — Windows-only on modern .NET. Switch to PngByteQRCode or SvgQRCode.
What does GetGraphic(20) mean?
Pixels per module, not total image size. Multiply by the module count of your code's version, plus the quiet zone, to predict output dimensions.
How do I return a QR code from ASP.NET?
Results.Bytes with the PngByteQRCode output and an image/png content type in a minimal API route. Add an immutable cache header since output is deterministic.
Try it — free, no signup
Related
- A free QR code API with no key — UseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight…
- Generate a QR code in Java — Java QR generation with ZXing — MultiFormatWriter, the EncodeHintType map, MatrixToImageWriter — and the keyless API via java.net.http.HttpClient.
- QR code libraries compared — A map of the QR library ecosystem — generation and decoding, by language, with licences and honest maintenance status. Pick by use case, not by stars.
- Why you should verify that a QR code decodes — Rendering a QR code proves nothing about whether it scans. Styling, colour, logos and print all consume error-correction budget invisibly. The only…