Base64 in C#
Encode and decode Base64 in C# using Convert.ToBase64String and Convert.FromBase64String. Includes file handling, streams, and .NET best practices.
Detailed Explanation
C# provides Base64 support through the System.Convert class, which has been available since .NET Framework 1.0. The API is straightforward but has some nuances worth understanding, especially around encoding and large data handling.
Basic encoding and decoding:
using System;
using System.Text;
// Encoding
string original = "Hello, World!";
byte[] bytes = Encoding.UTF8.GetBytes(original);
string encoded = Convert.ToBase64String(bytes);
// Result: "SGVsbG8sIFdvcmxkIQ=="
// Decoding
byte[] decodedBytes = Convert.FromBase64String(encoded);
string decoded = Encoding.UTF8.GetString(decodedBytes);
// Result: "Hello, World!"
File encoding:
// Encode a file to Base64
byte[] fileBytes = File.ReadAllBytes("image.png");
string base64File = Convert.ToBase64String(fileBytes);
// Decode Base64 to file
byte[] outputBytes = Convert.FromBase64String(base64File);
File.WriteAllBytes("output.png", outputBytes);
Formatting options: Convert.ToBase64String accepts a Base64FormattingOptions enum to control line breaks:
// Insert line breaks every 76 characters (MIME-compatible)
string formatted = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
// No line breaks (default)
string compact = Convert.ToBase64String(bytes, Base64FormattingOptions.None);
Span-based API (.NET Core 2.1+): For performance-critical code, use the span-based overloads to avoid unnecessary allocations:
// Encode with Span<T>
Span<byte> source = stackalloc byte[] { 72, 101, 108, 108, 111 };
Span<char> destination = stackalloc char[8];
Convert.TryToBase64Chars(source, destination, out int charsWritten);
// Decode with Span<T>
ReadOnlySpan<char> base64Span = "SGVsbG8=".AsSpan();
Span<byte> output = stackalloc byte[5];
Convert.TryFromBase64Chars(base64Span, output, out int bytesWritten);
Common mistakes:
- Using
Encoding.ASCII.GetBytes()instead ofEncoding.UTF8.GetBytes(). ASCII silently replaces non-ASCII characters with?, producing incorrect Base64 output for international text. - Not handling
FormatExceptionwhen decoding user-provided Base64 strings. Always validate input withConvert.TryFromBase64String()(available in .NET Core 2.1+) or wrap the call in a try-catch. - Loading very large files entirely into memory with
File.ReadAllBytes(). For files larger than a few hundred megabytes, useCryptoStreamwithToBase64Transformfor streaming.
Use Case
Converting user-uploaded profile pictures to Base64 for storage in an Azure Cosmos DB document where a separate blob storage account would add unnecessary infrastructure complexity.