Skip to content

Instantly share code, notes, and snippets.

@aspose-com-gists
Last active December 15, 2025 10:15
Show Gist options
  • Select an option

  • Save aspose-com-gists/7e439d899507487fb36bfa4ea3a76c8e to your computer and use it in GitHub Desktop.

Select an option

Save aspose-com-gists/7e439d899507487fb36bfa4ea3a76c8e to your computer and use it in GitHub Desktop.
Create custom message handlers using .NET API, get C# examples of their implementation for various user tasks

Handling Messages and Events in HTML Processing in C#

This gist repository contains C# examples that accompany the Message Handlers chapter in the Aspose.HTML for .NET documentation. These examples demonstrate how to process web service requests and responses using various message handlers, including logging execution time, implementing custom schemes, working with ZIP archives, managing network operation timeouts, and handling password-based authentication schemes.

What's Included?

In this repository, you will find code illustrating various popular use cases for message handlers, including:

  • Implementing Custom Schemes – Examples of creating a message handler to process requests for a custom URI scheme.
  • Working with ZIP Archives – Demonstrations of handling HTML documents and associated resources (images, styles, scripts) packed into a ZIP archive. Includes converting HTML from a ZIP archive to PDF and converting HTML from a ZIP archive to JPG.
  • Authentication – A simple example of creating a custom message handler for web requests using password-based authentication schemes such as Basic, Digest, NTLM, and Kerberos.
  • Logging Web Request Execution Time – Examples of tracking and logging the total execution time of a web request.
  • Network Timeouts – Practical examples of configuring and managing network timeouts.
  • Network Request Inspection – Examples of intercepting requests, blocking unwanted external network requests, and replacing URLs with other values.

How to Use These Examples

The C# code snippets are self-contained and intended to provide a quick start when learning and integrating Aspose.HTML for .NET into your own projects.

  1. Install the latest version of Aspose.HTML for .NET using NuGet.
  2. Browse the gists in this repository and copy the relevant code into your project.
  3. Adjust the paths, settings, and input parameters to fit your environment.
  4. Run your project to see the example in action.

You can download a free trial of Aspose.HTML for .NET and use a temporary license for unrestricted access.

Documentation

Comprehensive explanations and full context for each example can be found in the Message Handlers chapter of the official documentation.

Other Related Resources

Prerequisites

To run the examples, you need:

  • .NET 5.0, .NET Core, or .NET Framework installed on your machine.
  • Supported OS: Windows, Linux, macOS.
  • The Aspose.HTML for .NET library (you can install it via NuGet: Install-Package Aspose.Html).
Aspose.HTML for .NET – Message-Handlers
// Authenticate and load protected HTML with custom configuration using C#
// Learn more: https://docs.aspose.com/html/net/message-handlers/authentication/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Add the CredentialHandler to the chain of existing message handlers
INetworkService service = configuration.GetService<INetworkService>();
MessageHandlerCollection handlers = service.MessageHandlers;
handlers.Insert(0, new CredentialHandler());
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument("https://httpbin.org/basic-auth/username/securelystoredpassword", configuration);
// Set custom request timeout using a message handler
// Learn more: https://docs.aspose.com/html/net/message-handlers/network-timeouts/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Call the INetworkService which contains the functionality for managing network operations
INetworkService network = configuration.GetService<INetworkService>();
// Add the TimeoutMessageHandler to the top of existing message handler chain
network.MessageHandlers.Insert(0, new TimeoutMessageHandler());
// Prepare path to a source document file
string documentPath = Path.Combine(DataDir, "document.html");
// Create an HTML document with a custom configuration
using HTMLDocument document = new HTMLDocument(documentPath, configuration);
// Set request timeout when converting HTML to PDF
// Learn more: https://docs.aspose.com/html/net/message-handlers/network-timeouts/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Call the INetworkService which contains the functionality for managing network operations
INetworkService network = configuration.GetService<INetworkService>();
// Add the TimeoutMessageHandler to the top of existing message handler chain
network.MessageHandlers.Insert(0, new TimeoutMessageHandler());
// Prepare path to a source document file
string documentPath = Path.Combine(DataDir, "document.html");
// Prepare a path for converted file saving
string savePath = Path.Combine(OutputDir, "document.pdf");
// Convert HTML to PDF with customized configuration
Converter.ConvertHTML(documentPath, configuration, new PdfSaveOptions(), savePath);
// Convert HTML from a ZIP archive to JPG using C#
// Learn more: https://docs.aspose.com/html/net/message-handlers/convert-html-from-zip-archive-to-jpg/
// Add this line before you try to use the 'IBM437' encoding
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
// Prepare path to a source zip file
string documentPath = Path.Combine(DataDir, "test.zip");
// Prepare path for converted file saving
string savePath = Path.Combine(OutputDir, "zip-to-jpg.jpg");
// Create an instance of ZipArchiveMessageHandler
using ZipArchiveMessageHandler zip = new ZipArchiveMessageHandler(documentPath);
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Add ZipArchiveMessageHandler to the chain of existing message handlers
configuration
.GetService<INetworkService>()
.MessageHandlers.Add(zip);
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument("zip:///test.html", configuration);
// Create an instance of Rendering Options
ImageRenderingOptions options = new ImageRenderingOptions()
{
Format = ImageFormat.Jpeg
};
// Create an instance of Image Device
using ImageDevice device = new ImageDevice(options, savePath);
// Render ZIP to JPG
document.RenderTo(device);
// Convert HTML from a ZIP archive to PDF using C#
// Learn more: https://docs.aspose.com/html/net/message-handlers/convert-html-from-zip-archive-to-pdf/
// Add this line before you try to use the 'IBM437' encoding
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
// Prepare path to a source zip file
string documentPath = Path.Combine(DataDir, "test.zip");
// Prepare path for converted file saving
string savePath = Path.Combine(OutputDir, "zip-to-pdf.pdf");
// Create an instance of ZipArchiveMessageHandler
using ZipArchiveMessageHandler zip = new ZipArchiveMessageHandler(documentPath);
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Add ZipArchiveMessageHandler to the chain of existing message handlers
configuration
.GetService<INetworkService>()
.MessageHandlers.Add(zip);
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument("zip:///test.html", configuration);
// Create the PDF Device
using PdfDevice device = new PdfDevice(savePath);
// Render ZIP to PDF
document.RenderTo(device);
// Implement custom zip schema with request duration logging using C# message handlers
// Learn more: https://docs.aspose.com/html/net/message-handlers/time-logging/
// Add this line before you try to use the 'IBM437' encoding
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
// Prepare path to a source zip file
string documentPath = Path.Combine(DataDir, "test.zip");
// Prepare path for converted file saving
string savePath = Path.Combine(OutputDir, "zip-to-pdf-duration.pdf");
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
INetworkService service = configuration.GetService<INetworkService>();
MessageHandlerCollection handlers = service.MessageHandlers;
// Custom Schema: ZIP. Add ZipFileSchemaMessageHandler to the end of the pipeline
handlers.Add(new ZipFileSchemaMessageHandler(new Archive(documentPath)));
// Duration Logging. Add the StartRequestDurationLoggingMessageHandler at the first place in the pipeline
handlers.Insert(0, new StartRequestDurationLoggingMessageHandler());
// Add the StopRequestDurationLoggingMessageHandler to the end of the pipeline
handlers.Add(new StopRequestDurationLoggingMessageHandler());
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument("zip-file:///test.html", configuration);
// Create the PDF Device
using PdfDevice device = new PdfDevice(savePath);
// Render ZIP to PDF
document.RenderTo(device);
// Log network requests for HTML processing in C#
// Learn more: https://docs.aspose.com/html/net/message-handlers/custom-message-handler/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Add the LogMessageHandler to the chain of existing message handlers
INetworkService service = configuration.GetService<INetworkService>();
MessageHandlerCollection handlers = service.MessageHandlers;
handlers.Insert(0, new LogMessageHandler());
// Prepare path to a source document file
string documentPath = Path.Combine(DataDir, "input.htm");
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument(documentPath, configuration);
// Use CredentialHandler for basic authentication
// Learn more: https://docs.aspose.com/html/net/message-handlers/authentication/
// This message handler used basic autentifications request
public class CredentialHandler : MessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
context.Request.Credentials = new NetworkCredential("username", "securelystoredpassword");
context.Request.PreAuthenticate = true;
Next(context);
}
}
// Monitor network requests by custom protocol in C # using schema-based message filter and handler
// Learn more: https://docs.aspose.com/html/net/message-handlers/time-logging/
// Define the CustomSchemaMessageFilter class that is derived from the MessageFilter class
class CustomSchemaMessageFilter : MessageFilter
{
private readonly string schema;
public CustomSchemaMessageFilter(string schema)
{
this.schema = schema;
}
// Override the Match() method
public override bool Match(INetworkOperationContext context)
{
return string.Equals(schema, context.Request.RequestUri.Protocol.TrimEnd(':'));
}
}
// Define the CustomSchemaMessageHandler class that is derived from the MessageHandler class
abstract class CustomSchemaMessageHandler : MessageHandler
{
// Initialize an instance of the CustomSchemaMessageHandler class
protected CustomSchemaMessageHandler(string schema)
{
Filters.Add(new CustomSchemaMessageFilter(schema));
}
}
// Disable network requests when loading HTML
// Learn more: https://docs.aspose.com/html/net/message-handlers/network-requests/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Call the INetworkService which contains the functionality for managing network operations
INetworkService network = configuration.GetService<INetworkService>();
// Add the NetworkDisabledMessageHandler to the top of existing message handler chain
network.MessageHandlers.Insert(0, new NetworkDisabledMessageHandler());
// Prepare path to a source document file
string documentPath = Path.Combine(DataDir, "document.html");
// Create an HTML document with a custom configuration
using HTMLDocument document = new HTMLDocument(documentPath, configuration);
// Implement a message handler that prints a message about starting and finishing processing request
// Learn more: https://docs.aspose.com/html/net/message-handlers/custom-message-handler/
public class LogMessageHandler : MessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
Debug.WriteLine("Start processing request: " + context.Request.RequestUri);
// Invoke the next message handler in the chain
Next(context);
Debug.WriteLine("Finish processing request: " + context.Request.RequestUri);
}
}
// Define the NetworkChangeMessageHandler class that is derived from the MessageHandler class
public class NetworkChangeMessageHandler : MessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
if (context.Request.RequestUri.Protocol == "file:" || context.Request.RequestUri.Protocol == "base64:")
{
Next(context);
return;
}
context.Request.RequestUri = new Url(context.Request.RequestUri.Pathname, "http://localhost:8080");
}
}
// Disable external network access while allowing local and embedded resources
// Learn more: https://docs.aspose.com/html/net/message-handlers/network-requests/
// Define the NetworkDisabledMessageHandler class that is derived from the MessageHandler class
public class NetworkDisabledMessageHandler : MessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
if (context.Request.RequestUri.Protocol == "file:" ||
context.Request.RequestUri.Protocol == "base64:" ||
context.Request.RequestUri.Protocol == "about:")
Next(context);
}
}
// Track and log HTTP request durations using C# message handlers
// Learn more: https://docs.aspose.com/html/net/message-handlers/time-logging/
// Define the RequestDurationLoggingMessageHandler class that is derived from the MessageHandler class
abstract class RequestDurationLoggingMessageHandler : MessageHandler
{
private static ConcurrentDictionary<Url, Stopwatch> requests = new ConcurrentDictionary<Url, Stopwatch>();
protected void StartTimer(Url url)
{
requests.TryAdd(url, Stopwatch.StartNew());
}
protected TimeSpan StopTimer(Url url)
{
Stopwatch timer = requests[url];
timer.Stop();
return timer.Elapsed;
}
}
class StartRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
// Start the stopwatch
StartTimer(context.Request.RequestUri);
// Invoke the next message handler in the chain
Next(context);
}
}
class StopRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
// Stop the stopwatch
TimeSpan duration = StopTimer(context.Request.RequestUri);
// Print the result
Debug.WriteLine($"Elapsed: {duration:g}, resource: {context.Request.RequestUri.Pathname}");
// Invoke the next message handler in the chain
Next(context);
}
}
// Log request time with custom C# message handler
// Learn more: https://docs.aspose.com/html/net/message-handlers/web-request-execution-time/
// Define the TimeLoggerMessageHandler class that is derived from the MessageHandler class
public class TimeLoggerMessageHandler : MessageHandler
{
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
// Start the stopwatch
Stopwatch stopwatch = Stopwatch.StartNew();
// Invoke the next message handler in the chain
Next(context);
// Stop the stopwatch
stopwatch.Stop();
// Print the result
Debug.WriteLine("Request: " + context.Request.RequestUri);
Debug.WriteLine("Time: " + stopwatch.ElapsedMilliseconds + "ms");
}
}
// Set custom timeout for network requests in .NET HTML processing
// Learn more: https://docs.aspose.com/html/net/message-handlers/network-timeouts/
// Define the TimeoutMessageHandler class that is derived from the MessageHandler class
public class TimeoutMessageHandler : MessageHandler
{
public override void Invoke(INetworkOperationContext context)
{
context.Request.Timeout = TimeSpan.FromSeconds(1);
Next(context);
}
}
// Track HTML load time in C# using a custom network message handler
// Learn more: https://docs.aspose.com/html/net/message-handlers/web-request-execution-time/
// Create an instance of the Configuration class
using Configuration configuration = new Configuration();
// Add the TimeLoggerMessageHandler to the chain of existing message handlers
INetworkService service = configuration.GetService<INetworkService>();
MessageHandlerCollection handlers = service.MessageHandlers;
handlers.Insert(0, new TimeLoggerMessageHandler());
// Prepare path to a source document file
string documentPath = Path.Combine(DataDir, "input.htm");
// Initialize an HTML document with specified configuration
using HTMLDocument document = new HTMLDocument(documentPath, configuration);
// Implement ZipArchiveMessageHandler in C#
// Learn more: https://docs.aspose.com/html/net/message-handlers/convert-html-from-zip-archive-to-jpg/
// This message handler prints a message about start and finish processing request
class ZipArchiveMessageHandler : MessageHandler, IDisposable
{
private string filePath;
private Archive archive;
// Initialize an instance of the ZipArchiveMessageHandler class
public ZipArchiveMessageHandler(string path)
{
this.filePath = path;
Filters.Add(new ProtocolMessageFilter("zip"));
}
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
// Call the GetFile() method that defines the logic in the Invoke() method
byte[] buff = GetFile(context.Request.RequestUri.Pathname.TrimStart('/'));
if (buff != null)
{
// Checking: if a resource is found in the archive, then return it as a Response
context.Response = new ResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(buff)
};
context.Response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
}
else
{
context.Response = new ResponseMessage(HttpStatusCode.NotFound);
}
// Call the next message handler
Next(context);
}
byte[] GetFile(string path)
{
path = path.Replace(@"\", @"/");
ArchiveEntry result = GetArchive().Entries.FirstOrDefault(x => path == x.Name);
if (result != null)
{
using (Stream fs = result.Open())
using (MemoryStream ms = new MemoryStream())
{
fs.CopyTo(ms);
return ms.ToArray();
}
}
return null;
}
Archive GetArchive()
{
return archive ??= new Archive(filePath);
}
public void Dispose()
{
archive?.Dispose();
}
}
// Handle zip file protocol requests in c#
// Learn more: https://docs.aspose.com/html/net/message-handlers/time-logging/
// Define the ZipFileSchemaMessageHandler class that is derived from the CustomSchemaMessageHandler class
class ZipFileSchemaMessageHandler : CustomSchemaMessageHandler
{
private readonly Archive archive;
public ZipFileSchemaMessageHandler(Archive archive) : base("zip-file")
{
this.archive = archive;
}
// Override the Invoke() method
public override void Invoke(INetworkOperationContext context)
{
string pathInsideArchive = context.Request.RequestUri.Pathname.TrimStart('/').Replace("\\", "/");
Stream stream = GetFile(pathInsideArchive);
if (stream != null)
{
// If a resource is found in the archive, then return it as a Response
ResponseMessage response = new ResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(stream);
response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
context.Response = response;
}
else
{
context.Response = new ResponseMessage(HttpStatusCode.NotFound);
}
// Invoke the next message handler in the chain
Next(context);
}
Stream GetFile(string path)
{
ArchiveEntry result = archive
.Entries
.FirstOrDefault(x => x.Name == path);
return result?.Open();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment