Zeiterfassung – HTML konvertieren – C# Beispiel

In diesem Artikel finden Sie ein Beispiel für die Verwendung benutzerdefinierter Nachrichtenhandler zur Konvertierung von HTML aus einem ZIP-Archiv in PDF und zur Protokollierung der Ausführungszeit dieses Prozesses.

Um die Leistung zu optimieren, müssen Sie manchmal die Ausführungszeit von Webanfragen herausfinden. Sie möchten beispielsweise wissen, wie viel Zeit für die Konvertierung einer HTML-basierten Datei aus einem ZIP-Archiv in PDF benötigt wird.

Protokollierung der Ausführungszeit

Erstellen eines Nachrichten-Handlers für eine benutzerdefinierte Schema-Implementierung

Lassen Sie uns einen benutzerdefinierten Handler erstellen, den Sie für die Implementierung eines benutzerdefinierten Schemas (Protokolls) verwenden können. Führen Sie die nächsten Schritte aus:

  1. Verwenden Sie den erforderlichen Namespace, d. h. Aspose.Html.Net.
  2. Definieren Sie Ihre eigene CustomSchemaMessageHandler-Klasse, die von der MessageHandler-Klasse abgeleitet wird.
  3. Initialisieren Sie eine Instanz der Klasse CustomSchemaMessageHandler und definieren Sie eine Filter-Eigenschaft für sie.
  4. Erstellen Sie die Klasse CustomSchemaMessageFilter, die von der Klasse MessageFilter abgeleitet ist.
  5. Überschreiben Sie die Methode Match() der Klasse MessageFilter, um das Verhalten des benutzerdefinierten Nachrichten-Handlers zu implementieren.

Der folgende Codeschnipsel zeigt, wie die Klasse CustomSchemaMessageHandler erstellt wird:

 1// Monitor network requests by custom protocol in C # using schema-based message filter and handler
 2
 3// Define the CustomSchemaMessageFilter class that is derived from the MessageFilter class
 4class CustomSchemaMessageFilter : MessageFilter
 5{
 6    private readonly string schema;
 7    public CustomSchemaMessageFilter(string schema)
 8    {
 9        this.schema = schema;
10    }
11    // Override the Match() method
12    public override bool Match(INetworkOperationContext context)
13    {
14        return string.Equals(schema, context.Request.RequestUri.Protocol.TrimEnd(':'));
15    }
16}
17
18// Define the CustomSchemaMessageHandler class that is derived from the MessageHandler class
19abstract class CustomSchemaMessageHandler : MessageHandler
20{
21    // Initialize an instance of the CustomSchemaMessageHandler class
22    protected CustomSchemaMessageHandler(string schema)
23    {
24        Filters.Add(new CustomSchemaMessageFilter(schema));
25    }
26}

Der Konstruktor CustomSchemaMessageHandler(schema) instanziiert das CustomSchemaMessageHandler-Objekt und nimmt das schema als Parameter an. Die Add()-Methode fügt das CustomSchemaMessageFilter-Objekt an das Ende der Sammlung an. Die Match()-Methode prüft, ob ein “Kontext” die Filterkriterien erfüllt.

Erstellen des ZipFileSchemaMessageHandlers für die Arbeit mit ZIP-Archiven

Das folgende Codeschnipsel zeigt, wie man die Klasse ZipFileSchemaMessageHandler für die Arbeit mit ZIP-Archiven erstellt:

 1// Handle zip file protocol requests in c#
 2
 3// Define the ZipFileSchemaMessageHandler class that is derived from the CustomSchemaMessageHandler class
 4class ZipFileSchemaMessageHandler : CustomSchemaMessageHandler
 5{
 6    private readonly Archive archive;
 7
 8    public ZipFileSchemaMessageHandler(Archive archive) : base("zip-file")
 9    {
10        this.archive = archive;
11    }
12
13    // Override the Invoke() method
14    public override void Invoke(INetworkOperationContext context)
15    {
16        string pathInsideArchive = context.Request.RequestUri.Pathname.TrimStart('/').Replace("\\", "/");
17        Stream stream = GetFile(pathInsideArchive);
18
19        if (stream != null)
20        {
21            // If a resource is found in the archive, then return it as a Response
22            ResponseMessage response = new ResponseMessage(HttpStatusCode.OK);
23            response.Content = new StreamContent(stream);
24            response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
25            context.Response = response;
26        }
27        else
28        {
29            context.Response = new ResponseMessage(HttpStatusCode.NotFound);
30        }
31
32        // Invoke the next message handler in the chain
33        Next(context);
34    }
35
36    Stream GetFile(string path)
37    {
38        ArchiveEntry result = archive
39            .Entries
40            .FirstOrDefault(x => x.Name == path);
41        return result?.Open();
42    }
43}

Im obigen Beispiel wird nach einer Ressource (Zip-Archiv) unter ihrer URI gesucht. Wenn eine Ressource gefunden wird, gibt die Methode FromFileExtension() den MimeType der Ressource zurück.

Message Handler für eine Web-Anfrage Ausführungszeitprotokollierung

Das folgende Codeschnipsel zeigt, wie man StartRequestDurationLoggingMessageHandler und StopRequestDurationLoggingMessageHandler erstellt, um die Zeit für die Ausführung von Webanfragen zu protokollieren.

 1// Track and log HTTP request durations using C# message handlers
 2
 3// Define the RequestDurationLoggingMessageHandler class that is derived from the MessageHandler class
 4abstract class RequestDurationLoggingMessageHandler : MessageHandler
 5{
 6    private static ConcurrentDictionary<Url, Stopwatch> requests = new ConcurrentDictionary<Url, Stopwatch>();
 7
 8    protected void StartTimer(Url url)
 9    {
10        requests.TryAdd(url, Stopwatch.StartNew());
11    }
12
13    protected TimeSpan StopTimer(Url url)
14    {
15        Stopwatch timer = requests[url];
16        timer.Stop();
17        return timer.Elapsed;
18    }
19}
20
21class StartRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
22{
23    // Override the Invoke() method
24    public override void Invoke(INetworkOperationContext context)
25    {
26        // Start the stopwatch
27        StartTimer(context.Request.RequestUri);
28
29        // Invoke the next message handler in the chain
30        Next(context);
31    }
32}
33
34class StopRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
35{
36    // Override the Invoke() method
37    public override void Invoke(INetworkOperationContext context)
38    {
39        // Stop the stopwatch
40        TimeSpan duration = StopTimer(context.Request.RequestUri);
41
42        // Print the result
43        Debug.WriteLine($"Elapsed: {duration:g}, resource: {context.Request.RequestUri.Pathname}");
44
45        // Invoke the next message handler in the chain
46        Next(context);
47    }
48}

Hinzufügen der Nachrichten-Handler zur Pipeline

Das Schlüsselkonzept der Message-Handler besteht darin, sie miteinander zu verketten. Wir haben mehrere Message Handler erstellt und sollten sie in einer bestimmten Reihenfolge zur Pipeline hinzufügen, um das Beispiel der Zeitprotokollierung der HTML-Konvertierung von ZIP-Archiven in PDF zu implementieren. Führen wir die folgenden Schritte aus:

  1. Erstellen Sie eine Instanz der Klasse Configuration.
  2. Realisieren Sie das benutzerdefinierte ZIP-Schema. Verwenden Sie die Methode Add(), um ZipFileSchemaMessageHandler an das Ende der Pipeline anzuhängen.
  3. Ausführen der Dauerprotokollierung. Verwenden Sie die Insert()-Methode, um den StartRequestDurationLoggingMessageHandler zuerst in die Pipeline einzufügen, und die Add()-Methode, um den StopRequestDurationLoggingMessageHandler an das Ende der Pipeline anzuhängen.
  4. Initialisiert ein HTML-Dokument mit der angegebenen Konfiguration.
  5. Erstellen Sie das PDF-Gerät und rendern Sie HTML in PDF.
 1// Implement custom zip schema with request duration logging using C# message handlers
 2
 3// Add this line before you try to use the 'IBM437' encoding
 4System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
 5
 6// Prepare path to a source zip file
 7string documentPath = Path.Combine(DataDir, "test.zip");
 8
 9// Prepare path for converted file saving
10string savePath = Path.Combine(OutputDir, "zip-to-pdf-duration.pdf");
11
12// Create an instance of the Configuration class
13using Configuration configuration = new Configuration();
14INetworkService service = configuration.GetService<INetworkService>();
15MessageHandlerCollection handlers = service.MessageHandlers;
16
17// Custom Schema: ZIP. Add ZipFileSchemaMessageHandler to the end of the pipeline
18handlers.Add(new ZipFileSchemaMessageHandler(new Archive(documentPath)));
19
20// Duration Logging. Add the StartRequestDurationLoggingMessageHandler at the first place in the pipeline
21handlers.Insert(0, new StartRequestDurationLoggingMessageHandler());
22
23// Add the StopRequestDurationLoggingMessageHandler to the end of the pipeline
24handlers.Add(new StopRequestDurationLoggingMessageHandler());
25
26// Initialize an HTML document with specified configuration
27using HTMLDocument document = new HTMLDocument("zip-file:///test.html", configuration);
28
29// Create the PDF Device
30using PdfDevice device = new PdfDevice(savePath);
31
32// Render ZIP to PDF
33document.RenderTo(device);

Der Konstruktor Configuration() erzeugt eine Instanz der Klasse Configuration. Nachdem die Konfiguration erstellt wurde, werden die Methoden GetService<INetworkService>(), MessageHandlers.Add() und MessageHandlers.Insert() aufgerufen. Die Insert()- und Add()-Methoden fügen die benutzerdefinierten Message-Handler in die Sammlung der vorhandenen Message-Handler ein. Die Abbildung zeigt die Kette der Message-Handler für dieses Beispiel:

Text “Die Kette der Nachrichtenbearbeiter”

Hinweis: Der HTMLDocument(address, configuration) Konstruktor nimmt den absoluten Pfad zum ZIP-Archiv. Alle zugehörigen Ressourcen haben jedoch relative Pfade im HTML-Dokument und im Code des Beispiels.

Sie können die vollständigen Beispiele und Datendateien von GitHub herunterladen.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.