Exporting files to Backblaze B2 in .Net using open-source tools

Integrating cloud storage into your .NET applications can significantly enhance your data handling capabilities. This tutorial provides a step-by-step guide on exporting files to Backblaze B2 using modern open-source tools in C#, with robust error handling and retry mechanisms.
Introduction to Backblaze B2 cloud storage
Backblaze B2 offers cost-effective cloud storage with a straightforward API that makes integration simple. With competitive pricing starting at $0.005 per GB per month, it is an attractive option for storing and distributing files. As pricing details may change, always refer to the official Backblaze website for the most current information.
Setting up a Backblaze B2 account
To get started with Backblaze B2, follow these steps:
- Visit the Backblaze B2 sign-up page.
- Complete the registration process.
- Navigate to the Buckets section in your account dashboard.
- Create a new bucket to store your files.
- Generate application keys with the appropriate permissions.
Installing required .Net libraries
To interact with the Backblaze B2 API in .NET, install the actively maintained Backblaze.Agent library using the .NET CLI:
dotnet add package Backblaze.Agent
Authenticating with Backblaze B2 API in .Net
Configure Backblaze.Agent in your application's service collection as follows:
using Microsoft.Extensions.DependencyInjection;
using Bytewizer.Backblaze;
public void ConfigureServices(IServiceCollection services)
{
services.AddBackblazeAgent(options =>
{
options.KeyId = "YOUR_KEY_ID";
options.ApplicationKey = "YOUR_APPLICATION_KEY";
});
}
Uploading files to Backblaze B2 using C#
The following example demonstrates a robust service for handling file uploads to Backblaze B2. It leverages dependency injection, asynchronous operations, and the Polly library for implementing a retry policy.
using System;
using System.IO;
using System.Threading.Tasks;
using Bytewizer.Backblaze;
using Microsoft.Extensions.Logging;
using Polly;
using Polly.Retry;
public class BackblazeService
{
private readonly IStorageClient _storage;
private readonly ILogger<BackblazeService> _logger;
private readonly string _bucketId;
private readonly AsyncRetryPolicy<string> _retryPolicy;
public BackblazeService(IStorageClient storage, ILogger<BackblazeService> logger, string bucketId)
{
_storage = storage;
_logger = logger;
_bucketId = bucketId;
_retryPolicy = Policy<string>
.Handle<BackblazeException>()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, retryCount, context) =>
{
_logger.LogWarning(exception, "Retry {RetryCount} encountered an error. Waiting {TimeSpan} before next retry.", retryCount, timeSpan);
});
}
public async Task<string> UploadFileAsync(string filePath)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var fileName = Path.GetFileName(filePath);
try
{
using var stream = File.OpenRead(filePath);
var result = await _storage.Files.UploadAsync(_bucketId, fileName, stream);
_logger.LogInformation("File {FileName} uploaded successfully.", fileName);
return result.FileName;
}
catch (BackblazeException ex)
{
_logger.LogError(ex, "Backblaze upload failed for file {FileName}.", fileName);
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error during upload for file {FileName}.", fileName);
throw;
}
});
}
}
Integrating Backblaze uploads into your application
The following example shows how to incorporate the BackblazeService into an ASP.NET Core application for handling file uploads via an API endpoint.
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
[ApiController]
[Route("[controller]")]
public class FileUploadController : ControllerBase
{
private readonly BackblazeService _backblazeService;
private readonly ILogger<FileUploadController> _logger;
public FileUploadController(BackblazeService backblazeService, ILogger<FileUploadController> logger)
{
_backblazeService = backblazeService;
_logger = logger;
}
[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file selected.");
var tempPath = Path.GetTempFileName();
try
{
await using (var stream = new FileStream(tempPath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var uploadedFileName = await _backblazeService.UploadFileAsync(tempPath);
return Ok(new { fileName = uploadedFileName });
}
finally
{
if (System.IO.File.Exists(tempPath))
System.IO.File.Delete(tempPath);
}
}
}
Troubleshooting and best practices
When integrating Backblaze B2, consider the following best practices to ensure smooth operation:
- Verify your Backblaze account credentials and bucket ID are properly configured.
- Ensure your network connection is stable and that API rate limits are observed.
- Implement exponential backoff with a retry policy (as shown above) to handle transient errors.
- Monitor application logs closely to quickly diagnose and resolve issues.
- Consult the official Backblaze documentation for updates and troubleshooting tips.
Conclusion
Integrating Backblaze B2 into your .NET applications using modern open-source tools offers a robust solution for managing file uploads. The Backblaze.Agent library supports dependency injection, asynchronous operations, and configurable retry policies, making it an excellent choice for production-ready applications.
For additional file processing features, consider exploring Transloadit.