Zum Fußzeileninhalt springen
MIGRATIONSLEITFäDEN

Migrieren von PDFBolt zu IronPDF in C#

Durch die Migration von PDFBoltzuIronPDFwird Ihr .NET-PDF-Workflow von einem reinen Cloud-SaaS-Dienst mit externer Dokumentenverarbeitung zu einer selbst gehosteten Bibliothek mit vollständigem Datenschutz und unbegrenzter lokaler Generierung. Dieser Leitfaden bietet einen umfassenden, schrittweisen Migrationspfad, der Netzwerkabhängigkeiten, Nutzungsbeschränkungen und externe Datenübertragungen eliminiert und gleichzeitig den Zugang zu PDF-Bearbeitungsfunktionen ermöglicht, die PDFBoltnicht bieten kann.

Warum von PDFBoltzuIronPDFmigrieren

Das Cloud-Only-Problem

PDFBolt ist eine Cloud-only SaaS-Plattform, die Ihre Dokumente auf externen Servern verarbeitet. Diese Architektur ist zwar praktisch für schnelle Prototypen, stellt aber für Produktionsanwendungen eine große Herausforderung dar:

  1. Verarbeitung ausschließlich in der Cloud: Jedes Dokument durchläuft externe Server – eine selbstgehostete Option steht nicht zur Verfügung, was Unternehmen abschrecken könnte, die mehr Kontrolle über ihre Daten und Prozesse benötigen.

  2. Datenschutzrisiken: Sensible Dokumente (Verträge, Krankenakten, Finanzdaten) müssen extern übermittelt werden. Unternehmen, die mit sensiblen Informationen arbeiten, haben berechtigte Bedenken.

  3. Nutzungsbeschränkungen: Das kostenlose Kontingent ist auf 100 Dokumente pro Monat begrenzt, was für größere Unternehmen möglicherweise nicht ausreicht. Der Preis pro Dokument summiert sich bei Produktionsaufträgen schnell.

  4. Netzwerkabhängigkeit: Bei Internetausfällen oder Ausfallzeiten von PDFBoltwird die PDF-Generierung vollständig unterbrochen.

  5. Latenz: Die Netzwerk-Roundtrip-Zeit verlängert jede Konvertierung um Sekunden im Vergleich zur lokalen Verarbeitung.

  6. Compliance-Probleme: Die Durchführung von Audits gemäß DSGVO, HIPAA und SOC2 wird durch die externe Dokumentenverarbeitung erschwert.

  7. Sicherheit der API-Schlüssel: Durchgesickerte API-Schlüssel können zu unautorisierter Nutzung führen, die Ihrem Konto in Rechnung gestellt wird.

  8. Abhängigkeit vom Anbieter: Ihre Anwendung schlägt fehl, wenn PDFBoltdie Bedingungen ändert oder den Betrieb einstellt.

PDFBoltvsIronPDFVergleich

Betrifft PDFBolt IronPDF
Datenstandort Externe Server Nur Ihre Server
Nutzungseinschränkungen 100 kostenlos, dann pro Dokument Unbegrenzt
Internet erforderlich Ja, immer Nein
Latenzzeit Netzwerk-Round-Trip Millisekunden
Konformität Komplex (externe Bearbeitung) Einfach (lokale Verarbeitung)
Kostenmodell Pro Dokument Einmalig oder jährlich
Offline-Betrieb Unmöglich Vollständig unterstützt
API Hauptrisiken Durchgesickert = in Rechnung gestellt Lizenzschlüssel, kein Abrechnungsrisiko

Für Teams, die die Einführung von .NET 10 und C# 14 bis 2025 bzw. 2026 planen, bietetIronPDFeine selbst gehostete Grundlage, die vollständigen Datenschutz gewährleistet und die Abhängigkeit von externen Cloud-Diensten beseitigt.


Bevor Sie beginnen

Voraussetzungen

  1. .NET-Umgebung: .NET Framework 4.6.2+ oder .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet-Zugriff: Möglichkeit zur Installation von NuGet-Paketen
  3. IronPDF-Lizenz: Ihren Lizenzschlüssel erhalten Sie auf ironpdf.com.

NuGet-Paketänderungen

# Remove PDFBolt
dotnet remove package PDFBolt

# Install IronPDF
dotnet add package IronPdf
# Remove PDFBolt
dotnet remove package PDFBolt

# Install IronPDF
dotnet add package IronPdf
SHELL

Lizenz-Konfiguration

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Die Verwendung von PDFBolterkennen

# Find all PDFBoltreferences
grep -r "PDFBolt\|HtmlToPdfConverter\|ConvertHtmlString\|ConvertUrl" --include="*.cs" .

# Find API key references
grep -r "PDFBOLT\|ApiKey" --include="*.cs" --include="*.json" --include="*.config" .
# Find all PDFBoltreferences
grep -r "PDFBolt\|HtmlToPdfConverter\|ConvertHtmlString\|ConvertUrl" --include="*.cs" .

# Find API key references
grep -r "PDFBOLT\|ApiKey" --include="*.cs" --include="*.json" --include="*.config" .
SHELL

Komplette API-Referenz

Kernklassen-Zuordnungen

PDFBolt IronPDF Notizen
new HtmlToPdfConverter() new ChromePdfRenderer() Haupt-Renderer
Seitengröße PdfPaperSize Enum für Papierformate
(gibt byte[] zurück)_ PdfDocument Reichhaltiges Dokument-Objekt

Konvertierungsmethoden-Zuordnungen

PDFBolt IronPDF Notizen
converter.ConvertHtmlString(html) renderer.RenderHtmlAsPdf(html) Liefert PdfDocument
converter.ConvertUrl(url) renderer.RenderUrlAsPdf(url) Liefert PdfDocument

Zuordnungen von Ausgabemethoden

PDFBolt IronPDF Notizen
File.WriteAllBytes(path, pdf) pdf.SaveAs(Pfad) Direkte Speichermethode
(pdf ist byte[]) pdf.BinaryData Byte-Array abrufen
(manueller Stream)_ pdf.Stream Stream-Eigenschaft

Zuordnungen der Seitenkonfiguration

PDFBolt IronPDF Notizen
converter.PageSize = PageSize.A4 renderer.RenderingOptions.PaperSize = PdfPaperSize.A4 Papierformat enum
converter.MarginTop = 20 renderer.RenderingOptions.MarginTop = 20 In Millimetern
converter.MarginBottom = 20 renderer.RenderingOptions.MarginBottom = 20 In Millimetern
converter.MarginLeft = 15 renderer.RenderingOptions.MarginLeft = 15 In Millimetern
converter.MarginRight = 15 renderer.RenderingOptions.MarginRight = 15 In Millimetern

Kopf-/Fußzeilen-Platzhalter-Zuordnungen

PDFBolt IronPDF Notizen
{Seitennummer} {Seite} Aktuelle Seite
{gesamteSeiten} {Gesamtseiten} Seiten insgesamt
{Datum} {Datum} Gleiche
{Titel} {html-title} Titel des Dokuments

Beispiele für die Code-Migration

Beispiel 1: Grundlegendes HTML zu PDF

Vor (PDFBolt):

// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = converter.ConvertHtmlString(html);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = converter.ConvertHtmlString(html);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

Nach (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Der grundlegende Unterschied ist der Rückgabetyp und das Speichermuster. PDFBolt's HtmlToPdfConverter.ConvertHtmlString() liefert ein Byte[], das Sie manuell mit File.WriteAllBytes() auf die Festplatte schreiben müssen. Dazu ist es erforderlich, System.IO zu importieren und die Dateioperationen selbst durchzuführen.

IronPDF's ChromePdfRenderer.RenderHtmlAsPdf() gibt ein PdfDocumentObjekt mit einer integrierten SaveAs() Methode zurück. Dieser objektorientierte Ansatz bietet zusätzliche Vorteile: Sie können die PDF-Datei vor dem Speichern manipulieren (Wasserzeichen hinzufügen, Dokumente zusammenführen, Sicherheit hinzufügen). Wenn Sie die Rohbytes für die Kompatibilität mit bestehendem Code benötigen, verwenden Sie pdf.BinaryData. Weitere Rendering-Optionen finden Sie in der HTML to PDF Dokumentation.

Beispiel 2: Konvertierung von URL in PDF

Vor (PDFBolt):

// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var pdf = converter.ConvertUrl("https://www.example.com");
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var pdf = converter.ConvertUrl("https://www.example.com");
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

Nach (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

Das PDFBolt-Muster für die URL-Konvertierung folgt demselben Ansatz wie die HTML-Konvertierung: ConvertUrl() liefert Byte[] und erfordert File.WriteAllBytes() zum Speichern. Beachten Sie, dass PDFBoltimmer noch einen Netzwerk-Roundtrip zu seinen Servern benötigt, auch wenn Sie bereits von einer URL abrufen.

Die Methode RenderUrlAsPdf() vonIronPDFgibt ein PdfDocumentmit der integrierten Methode SaveAs() zurück. Der Hauptvorteil besteht darin, dassIronPDFden URL-Abruf und das PDF-Rendering lokal durchführt - keine Daten verlassen Ihre Infrastruktur. Beachten Sie, dass die IronPDF-Version für diesen einfachen Fall nicht einmal System.IO; verwenden muss. Erfahren Sie mehr über die URL in PDF Konvertierung.

Beispiel 3: HTML-Datei mit benutzerdefinierten Seiteneinstellungen

Vor (PDFBolt):

// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        converter.PageSize = PageSize.A4;
        converter.MarginTop = 20;
        converter.MarginBottom = 20;
        var html = File.ReadAllText("input.html");
        var pdf = converter.ConvertHtmlString(html);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package PDFBolt
using PDFBolt;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        converter.PageSize = PageSize.A4;
        converter.MarginTop = 20;
        converter.MarginBottom = 20;
        var html = File.ReadAllText("input.html");
        var pdf = converter.ConvertHtmlString(html);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
$vbLabelText   $csharpLabel

Nach (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 20;
        renderer.RenderingOptions.MarginBottom = 20;
        var html = File.ReadAllText("input.html");
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 20;
        renderer.RenderingOptions.MarginBottom = 20;
        var html = File.ReadAllText("input.html");
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Dieses Beispiel zeigt die Unterschiede in der Seitenkonfiguration. PDFBoltsetzt Eigenschaften direkt auf das Konverterobjekt (converter.PageSize, converter.MarginTop).IronPDFverwendet ein RenderingOptions Objekt auf dem Renderer (renderer.RenderingOptions.PaperSize, renderer.RenderingOptions.MarginTop).

Die wichtigsten Mappings:

  • PageSize.A4PdfPaperSize.A4 (anderer Enum-Name)
  • MarginTop = 20RenderingOptions.MarginTop = 20 (über RenderingOptions)

Beide verwenden Millimeter für Randwerte, so dass Ihre vorhandenen Randwerte direkt übertragen werden sollten. Der IronPdf.Rendering-Namensraum wird für den Zugriff auf das PdfPaperSize-Enum benötigt. Weitere Optionen für die Seitenkonfiguration finden Sie in der Dokumentation der Darstellungsoptionen.


Kritische Hinweise zur Migration

Rückgabetyp ändern

PDFBolt gibt Byte[] direkt zurück;IronPDFliefert PdfDocument:

// PDFBoltpattern:
byte[] pdf = converter.ConvertHtmlString(html);
File.WriteAllBytes("output.pdf", pdf);

//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
// PDFBoltpattern:
byte[] pdf = converter.ConvertHtmlString(html);
File.WriteAllBytes("output.pdf", pdf);

//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
$vbLabelText   $csharpLabel

Änderung der Klassennamen

Der Name der Hauptklasse wird von "Konverter" in "Renderer" geändert:

// PDFBolt
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
// PDFBolt
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

Änderung von Konfigurationsmustern

PDFBolt verwendet direkte Eigenschaften;IronPDFverwendet RenderingOptions:

// PDFBolt: Direct properties
converter.PageSize = PageSize.A4;
converter.MarginTop = 20;

// IronPDF: Via RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
// PDFBolt: Direct properties
converter.PageSize = PageSize.A4;
converter.MarginTop = 20;

// IronPDF: Via RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
$vbLabelText   $csharpLabel

API-Schlüssel-Eliminierung

PDFBolt erfordert die Verwaltung von API-Schlüsseln pro Anfrage;IronPDFverwendet einen einmaligen Lizenzschlüssel:

// PDFBolt: API key per client (security risk if leaked)
var apiKey = config["PDFBolt:ApiKey"];
var client = new Client(apiKey);

// IronPDF: License key once at startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
// PDFBolt: API key per client (security risk if leaked)
var apiKey = config["PDFBolt:ApiKey"];
var client = new Client(apiKey);

// IronPDF: License key once at startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

Entfernen der Netzwerk-Fehlerbehandlung

Lokale Verarbeitung bedeutet, dass keine Netzwerkfehler zu behandeln sind:

// PDFBolt: Network error handling required
catch (HttpRequestException ex)
catch (TaskCanceledException)
catch (TimeoutException)

// IronPDF: Remove network-specific catches entirely
// PDFBolt: Network error handling required
catch (HttpRequestException ex)
catch (TaskCanceledException)
catch (TimeoutException)

// IronPDF: Remove network-specific catches entirely
$vbLabelText   $csharpLabel

Neue Funktionen verfügbar

Nach der Migration aufIronPDFerhalten Sie Funktionen, die PDFBoltnicht bieten kann:

// PDF Merging (not available in PDFBolt)
var merged = PdfDocument.Merge(pdf1, pdf2);

// Watermarks (not available in PDFBolt)
pdf.ApplyWatermark("<h1 style='opacity:0.3;'>DRAFT</h1>");

// Password Protection (not available in PDFBolt)
pdf.SecuritySettings.UserPassword = "secret";

// Text Extraction (not available in PDFBolt)
string text = pdf.ExtractAllText();

// PDF to Images (not available in PDFBolt)
pdf.RasterizeToImageFiles("page_*.png");
// PDF Merging (not available in PDFBolt)
var merged = PdfDocument.Merge(pdf1, pdf2);

// Watermarks (not available in PDFBolt)
pdf.ApplyWatermark("<h1 style='opacity:0.3;'>DRAFT</h1>");

// Password Protection (not available in PDFBolt)
pdf.SecuritySettings.UserPassword = "secret";

// Text Extraction (not available in PDFBolt)
string text = pdf.ExtractAllText();

// PDF to Images (not available in PDFBolt)
pdf.RasterizeToImageFiles("page_*.png");
$vbLabelText   $csharpLabel

Fehlerbehebung

Ausgabe 1: HtmlToPdfConverter nicht gefunden

Problem: Die Klasse HtmlToPdfConverter existiert inIronPDFnicht.

Lösung: ChromePdfRenderer verwenden:

// PDFBolt
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
// PDFBolt
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

Ausgabe 2: ConvertHtmlString nicht gefunden

Problem: ConvertHtmlString() Methode existiert nicht.

Lösung: Verwenden Sie RenderHtmlAsPdf() :

// PDFBolt
var pdf = converter.ConvertHtmlString(html);

// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
// PDFBolt
var pdf = converter.ConvertHtmlString(html);

// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

Ausgabe 3: ConvertUrl nicht gefunden

Problem: ConvertUrl() -Methode existiert nicht.

Lösung: Verwenden Sie RenderUrlAsPdf() :

// PDFBolt
var pdf = converter.ConvertUrl(url);

// IronPDF
var pdf = renderer.RenderUrlAsPdf(url);
// PDFBolt
var pdf = converter.ConvertUrl(url);

// IronPDF
var pdf = renderer.RenderUrlAsPdf(url);
$vbLabelText   $csharpLabel

Ausgabe 4: PageSize Enum nicht gefunden

Problem: SeitengrößeEnum-Wert existiert nicht.

Lösung: Verwenden Sie PdfPaperSizeaus IronPdf.Rendering :

// PDFBolt
converter.PageSize = PageSize.A4;

// IronPDF
using IronPdf.Rendering;
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// PDFBolt
converter.PageSize = PageSize.A4;

// IronPDF
using IronPdf.Rendering;
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
$vbLabelText   $csharpLabel

Ausgabe 5: Erste PDF-Erzeugung ist langsam

Problem: Das erste Rendern dauert länger als erwartet.

Lösung: Die Chromium-Engine initialisiert sich bei der ersten Verwendung. Bei Bedarf vorwärmen:

// Warm up during application startup
var renderer = new ChromePdfRenderer();
renderer.RenderHtmlAsPdf("<html><body></body></html>");
// Warm up during application startup
var renderer = new ChromePdfRenderer();
renderer.RenderHtmlAsPdf("<html><body></body></html>");
$vbLabelText   $csharpLabel

Migrations-Checkliste

Vor der Migration

  • Alle PDFBolt-Verwendungen im Quellcode erfassen
  • Dokumentieren Sie die aktuellen Seitenkonfigurationseinstellungen (Seitengröße, Ränder)
  • API-Schlüsselverwaltungscode identifizieren, der entfernt werden soll
  • Geben Sie alle Ratenbegrenzungen oder Netzwerkfehlerbehandlungen an, die gelöscht werden sollen
  • IronPDF-Lizenzschlüssel erhalten

Paketänderungen

  • PDFBolt NuGet-Paket entfernen
  • Installieren Sie IronPdf NuGet-Paket: dotnet add package IronPdf
  • Hinzufügen using IronPdf; Namespace
  • Fügen Sie using IronPdf.Rendering; für Papiergrößen-Enumerationen

Code-Änderungen

  • Lizenzschlüsselkonfiguration beim Start hinzufügen
  • Ersetzen Sie HtmlToPdfConverter durch ChromePdfRenderer
  • Ersetzen Sie ConvertHtmlString() durch RenderHtmlAsPdf()
  • Ersetzen Sie ConvertUrl() durch RenderUrlAsPdf()
  • Ersetzen Sie File.WriteAllBytes() durch pdf.SaveAs()
  • Aktualisiere Seitengrößeauf RenderingOptions.PaperSize
  • Aktualisieren Sie die Randeigenschaften auf RenderingOptions.MarginTop usw.
  • API-Schlüsselverwaltungscode entfernen
  • Code zur Ratenbegrenzung entfernen
  • Netzwerkfehlerbehandlung entfernen

Nach der Migration

  • API-Schlüssel aus Konfigurationsdateien löschen
  • API-Schlüssel aus Secret Managern entfernen
  • Führen Sie alle Tests durch und vergleichen Sie die PDF-Ausgabe.
  • Überprüfen Sie, ob Seitengrößen und Ränder korrekt dargestellt werden.
  • Erwägen Sie die Hinzufügung neuer Funktionen (Wasserzeichen, Sicherheit, Zusammenführung)

Curtis Chau
Technischer Autor

Curtis Chau hat einen Bachelor-Abschluss in Informatik von der Carleton University und ist spezialisiert auf Frontend-Entwicklung mit Expertise in Node.js, TypeScript, JavaScript und React. Leidenschaftlich widmet er sich der Erstellung intuitiver und ästhetisch ansprechender Benutzerschnittstellen und arbeitet gerne mit modernen Frameworks sowie der Erstellung gut strukturierter, optisch ansprechender ...

Weiterlesen