Email Format Converter for .NET

The Aspose.Email LowCode Converter provides a simplified, high-level API for converting email messages between different formats with minimal code complexity. This developer guide covers the core functionality, implementation patterns, and best practices for using the converter in .NET applications.

Aspose.Email.LowCode

The Aspose.Email.LowCode namespace contains classes designed to streamline email format conversion operations. The primary component is the Converter class, which offers static methods for transforming email messages between popular formats including EML, MSG, HTML, MHT, and MHTML.

Key Components

  • Converter: Static conversion methods for email format transformation
  • IOutputHandler: Interface for handling converted output streams
  • FolderOutputHandler: Built-in implementation for folder-based output storage

Getting Started

Installation

Install the Aspose.Email package via NuGet Package Manager:

Install-Package Aspose.Email

Namespace Declaration

using Aspose.Email.LowCode;
using System.IO;
using System.Threading.Tasks;

Core Conversion Methods

Generic Format Conversion

The Convert method provides flexible format conversion with explicit output type specification:

public static Task Convert(Stream input, string nameWithExtension, IOutputHandler handler, string outputType)

Example Implementation:

using var inputStream = File.OpenRead("email.eml");
var outputHandler = new FolderOutputHandler(@"C:\ConvertedEmails");

await Converter.Convert(inputStream, "email.eml", outputHandler, "html");

Specialized Conversion Methods

The converter provides dedicated methods for common conversion scenarios:

Converting to HTML Format

await Converter.ConvertToHtml(inputStream, "email.eml", outputHandler);

Converting to MSG Format

await Converter.ConvertToMsg(inputStream, "email.eml", outputHandler);

Converting to EML Format

await Converter.ConvertToEml(inputStream, "email.msg", outputHandler);

Converting to MHTML/MHT Formats

await Converter.ConvertToMhtml(inputStream, "email.eml", outputHandler);
await Converter.ConvertToMht(inputStream, "email.eml", outputHandler);

EML/MSG Specific Conversion

For automatic format detection between EML and MSG formats:

await Converter.ConvertEmlOrMsg(inputStream, "email.eml", outputHandler, "html");

Output Handler Implementation

Using FolderOutputHandler

The built-in FolderOutputHandler class automatically saves converted files to a specified directory:

public class FolderOutputHandler : IOutputHandler
{
    public FolderOutputHandler(string path)
    public string Path { get; set; }
}

Usage Example:

var outputHandler = new FolderOutputHandler(@"C:\OutputDirectory");

Custom Output Handler

Implement the IOutputHandler interface for custom output processing:

public class CustomOutputHandler : IOutputHandler
{
    public async Task AddOutputStream(string name, Func<Stream, Task> writeAction)
    {
        // Custom async implementation
        using var customStream = CreateCustomStream(name);
        await writeAction(customStream);
    }
    
    public void AddOutputStream(string name, Action<Stream> writeAction)
    {
        // Custom synchronous implementation
        using var customStream = CreateCustomStream(name);
        writeAction(customStream);
    }
}

Supported Format Matrix

Input FormatOutput FormatsMethod
EMLHTML, MSG, MHTML, MHTConvertToHtml(), ConvertToMsg(), etc.
MSGHTML, EML, MHTML, MHTConvertToHtml(), ConvertToEml(), etc.
Any Email FormatUser-specifiedConvert() with output type parameter

Advanced Implementation Patterns

Batch Processing Implementation

public class EmailBatchConverter
{
    private readonly IOutputHandler _outputHandler;
    
    public EmailBatchConverter(IOutputHandler outputHandler)
    {
        _outputHandler = outputHandler;
    }
    
    public async Task ConvertBatch(IEnumerable<string> emailFiles, string outputFormat)
    {
        var conversionTasks = emailFiles.Select(async file =>
        {
            using var stream = File.OpenRead(file);
            var fileName = Path.GetFileName(file);
            
            await Converter.Convert(stream, fileName, _outputHandler, outputFormat);
        });
        
        await Task.WhenAll(conversionTasks);
    }
}

Error Handling Pattern

public async Task<ConversionResult> SafeConvert(string inputFile, string outputFormat)
{
    try
    {
        using var inputStream = File.OpenRead(inputFile);
        var outputHandler = new FolderOutputHandler(@"C:\Output");
        var fileName = Path.GetFileName(inputFile);
        
        await Converter.Convert(inputStream, fileName, outputHandler, outputFormat);
        
        return new ConversionResult { Success = true };
    }
    catch (Exception ex)
    {
        return new ConversionResult 
        { 
            Success = false, 
            ErrorMessage = ex.Message 
        };
    }
}

Memory-Optimized Stream Processing

public async Task ConvertWithMemoryOptimization(string inputFile)
{
    using var inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true);
    var outputHandler = new FolderOutputHandler(@"C:\Output");
    
    await Converter.ConvertToHtml(inputStream, Path.GetFileName(inputFile), outputHandler);
}

Configuration and Customization

Output Directory Structure

When using FolderOutputHandler, the converter maintains the original file structure:

var outputHandler = new FolderOutputHandler(@"C:\ConvertedEmails");
// Original: sample.eml → Output: C:\ConvertedEmails\sample.html

Custom Naming Strategy

Implement custom file naming through a specialized output handler:

public class TimestampOutputHandler : IOutputHandler
{
    private readonly string _basePath;
    
    public TimestampOutputHandler(string basePath)
    {
        _basePath = basePath;
    }
    
    public async Task AddOutputStream(string name, Func<Stream, Task> writeAction)
    {
        var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
        var newName = $"{timestamp}_{name}";
        var filePath = Path.Combine(_basePath, newName);
        
        using var fileStream = File.Create(filePath);
        await writeAction(fileStream);
    }
    
    // Synchronous implementation omitted for brevity
}

Performance Considerations

Asynchronous Operations

All conversion methods return Task objects, enabling efficient asynchronous processing:

public async Task ProcessMultipleEmailsAsync()
{
    var tasks = new[]
    {
        ConvertEmailAsync("email1.eml"),
        ConvertEmailAsync("email2.msg"),
        ConvertEmailAsync("email3.eml")
    };
    
    await Task.WhenAll(tasks);
}

Resource Management

Proper stream disposal is critical for optimal performance:

// Correct pattern
using (var inputStream = File.OpenRead("email.eml"))
{
    await Converter.ConvertToHtml(inputStream, "email.eml", outputHandler);
}

// Alternative using statement
using var inputStream = File.OpenRead("email.eml");
await Converter.ConvertToHtml(inputStream, "email.eml", outputHandler);

Memory Usage Optimization

For large email files, consider streaming approaches:

public async Task ConvertLargeEmail(string inputPath)
{
    const int bufferSize = 65536; // 64KB buffer
    
    using var inputStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true);
    var outputHandler = new FolderOutputHandler(@"C:\Output");
    
    await Converter.ConvertToHtml(inputStream, Path.GetFileName(inputPath), outputHandler);
}

Integration Examples

ASP.NET Core Web API Integration

[ApiController]
[Route("api/[controller]")]
public class EmailConverterController : ControllerBase
{
    [HttpPost("convert")]
    public async Task<IActionResult> ConvertEmail(IFormFile emailFile, [FromQuery] string format = "html")
    {
        if (emailFile == null || emailFile.Length == 0)
            return BadRequest("No file provided");
        
        try
        {
            using var inputStream = emailFile.OpenReadStream();
            var outputHandler = new MemoryOutputHandler();
            
            await Converter.Convert(inputStream, emailFile.FileName, outputHandler, format);
            
            return File(outputHandler.GetContent(), GetContentType(format), $"converted.{format}");
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Conversion failed: {ex.Message}");
        }
    }
    
    private string GetContentType(string format) => format.ToLower() switch
    {
        "html" => "text/html",
        "mhtml" => "message/rfc822",
        "eml" => "message/rfc822",
        _ => "application/octet-stream"
    };
}

Windows Service Implementation

public class EmailConverterService : BackgroundService
{
    private readonly string _watchFolder;
    private readonly string _outputFolder;
    
    public EmailConverterService(IConfiguration config)
    {
        _watchFolder = config["EmailConverter:WatchFolder"];
        _outputFolder = config["EmailConverter:OutputFolder"];
    }
    
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var watcher = new FileSystemWatcher(_watchFolder, "*.eml");
        watcher.Created += async (sender, e) => await ProcessEmailFile(e.FullPath);
        watcher.EnableRaisingEvents = true;
        
        while (!stoppingToken.IsCancellationRequested)
        {
            await Task.Delay(1000, stoppingToken);
        }
    }
    
    private async Task ProcessEmailFile(string filePath)
    {
        using var inputStream = File.OpenRead(filePath);
        var outputHandler = new FolderOutputHandler(_outputFolder);
        
        await Converter.ConvertToHtml(inputStream, Path.GetFileName(filePath), outputHandler);
    }
}

Troubleshooting

Common Issues and Solutions

IssueSolution
FileNotFoundExceptionVerify input file path and permissions
UnauthorizedAccessExceptionCheck output directory write permissions
OutOfMemoryExceptionUse streaming approach for large files
InvalidOperationExceptionEnsure valid email format for input file

Debugging Tips

Enable detailed logging for troubleshooting:

public async Task ConvertWithLogging(string inputFile)
{
    var logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<EmailConverter>();
    
    try
    {
        logger.LogInformation($"Starting conversion of {inputFile}");
        
        using var inputStream = File.OpenRead(inputFile);
        var outputHandler = new FolderOutputHandler(@"C:\Output");
        
        await Converter.ConvertToHtml(inputStream, Path.GetFileName(inputFile), outputHandler);
        
        logger.LogInformation($"Successfully converted {inputFile}");
    }
    catch (Exception ex)
    {
        logger.LogError(ex, $"Failed to convert {inputFile}");
        throw;
    }
}
 English