How to Fix EvoHtmlToPdfClient PDF Conversion in Xamarin.Forms
Diagnose EVO PDF Server connections, missing assets, scaling, JavaScript, sessions, licensing, and Xamarin.Forms deployment issues step by step.
Start with the architecture: EvoHtmlToPdfClient is a client library. The conversion engine runs in a separately installed EVO PDF Server. In Xamarin.Forms, the client code belongs in the platform project that actually performs the conversion, and the server address must be reachable from that runtime environment.
A 127.0.0.1:40001 error usually means the server is not installed, not running, listening on another port, or unreachable from the device or emulator. Fix connectivity first, then classify the output problem: missing resources, incorrect scaling, incomplete JavaScript content, lost session state, or a demo watermark.
1. Confirm the Xamarin.Forms and EVO deployment model
- Identify the exact NuGet package and assembly loaded by the iOS, Android, macOS, or other platform project.
- Install EVO PDF Server on a machine that the application runtime can reach. The official Xamarin integration instructions require the server before initializing the client.
- Record the server host, TCP port, service password or web-service URL, and firewall rules.
- Check what
127.0.0.1means where the app runs. On a physical phone, loopback normally refers to the phone itself, not the developer workstation. Verify this for your emulator, device, container, or hosted environment. - Use the namespace and constructor documented for your package generation. Legacy API material names
EvoPdf.HtmlToPdfClientandEvoHtmlToPdfClient.dllversion 9.0.0.0, while the Xamarin example usesEvoPdfClient. Do not mix those examples without checking the referenced assembly.
Minimal C# diagnostic conversion
The following is a small diagnostic shape. Match the constructor, key property, output method, and namespace to the assembly installed in your project.
using System;
using System.IO;
using EvoPdfClient; // Some legacy packages use EvoPdf.HtmlToPdfClient
public static class PdfDiagnostic
{
public static byte[] ConvertUrl(string serverHost, string url, string licenseKey)
{
// Use the constructor documented by your installed EVO package.
var converter = new HtmlToPdfConverter(serverHost);
converter.LicenseKey = licenseKey;
converter.NavigationTimeout = 60;
converter.ConversionDelay = 2;
var outputPath = Path.Combine(Path.GetTempPath(), "evo-diagnostic.pdf");
converter.ConvertUrlToPdf(url, outputPath);
return File.ReadAllBytes(outputPath);
}
}
If your package exposes a stream-returning method or a different converter type, keep the diagnostic sequence but replace only the version-specific members. A compile error at this stage is an API/version mismatch, not an HTML rendering failure.
2. Fix “Could not connect to server IP 127.0.0.1 on port 40001”
EVO’s troubleshooting guidance says this error indicates that the PDF Server is not installed or is inaccessible at the address configured in the client.
| Check | What to verify | Typical fix |
|---|---|---|
| Service state | The EVO PDF Server service or process is running. | Start or reinstall the server service. |
| Host value | The configured host is reachable from the app process. | Replace device-local loopback with the reachable workstation or server address. |
| Port | The client port matches the server listener. | Correct the port or server configuration. |
| Firewall | Inbound traffic is allowed on the server port. | Add a narrowly scoped firewall rule and retest. |
| Network route | Device, emulator, and server share a route. | Test from the same runtime environment, not only from the development machine. |
| Authentication | Any service password or web-service credentials match. | Update the client configuration. |
Reduce the test to a plain HTML string or a public URL. If both fail, keep investigating transport. If a plain conversion succeeds, restore your real URL, assets, scripts, and authentication one at a time.
3. Diagnose missing CSS and images
The converter server fetches resources from its own environment. An image that loads in the phone’s browser may be unavailable to the server because of DNS, private networking, authentication, certificate validation, or an invalid URL.
- Use absolute
https://URLs for external stylesheets, fonts, and images while diagnosing. - For an HTML string containing relative references, supply the correct base URL using the API member provided by your package, or rewrite references as absolute URLs.
- For local files, use correctly formatted file URLs and confirm that the server process can read them. A path on the mobile device is not automatically a path on the conversion server.
- Check redirects, expired certificates, robots or access controls, and resources requiring cookies or Authorization headers.
- Save the generated HTML and open it from the server environment to distinguish malformed markup from a network-access problem.
var html = "<html><head><link rel='stylesheet' href='https://www.example.com/app.css'></head>" +
"<body><img src='https://www.example.com/images/logo.png'></body></html>";
// Configure the package's documented base-URL option when using relative links.
// Convert the string only after confirming the server can fetch both resources.
4. Correct smaller text or images
Scaling is controlled by the browser viewport, page size, and fit-to-page behavior. Legacy EVO API documentation lists a 1024-pixel default HtmlViewerWidth. Its troubleshooting guide suggests trying approximately 800 pixels or disabling FitWidth when A4 portrait output is being scaled unexpectedly. Treat those values as version-specific trials.
- Record the intended paper size and orientation.
- Compare output with fit-to-page enabled and disabled.
- Try a narrower viewer width, such as 800 pixels, and inspect line wrapping.
- Check CSS print rules, fixed-width containers, transforms, and device-pixel assumptions.
- Confirm that a current EVO PDF Next default is not being mistaken for a legacy Xamarin default; release notes describe a 1024-pixel browser window scaled to fixed A4 in v14.75.
5. Include JavaScript, AJAX, and lazy content
Conversion can begin before asynchronous content is ready. The legacy API reference documents a two-second default ConversionDelay, while EVO also documents automatic behavior and manual triggering for pages that can signal readiness.
| Strategy | Use when | Trade-off |
|---|---|---|
| Fixed delay | Content normally finishes within a predictable interval. | Simple, but too short produces incomplete PDFs and too long wastes time. |
| Automatic mode or zero delay | The page is static and has no asynchronous work. | Fastest for static pages; unsafe for AJAX pages. |
| Manual trigger | Your page can signal that rendering is complete. | Most deterministic, but requires a page-side readiness mechanism supported by your EVO version. |
Wait for the actual data-rendering event rather than merely waiting for the DOM to exist. Test fonts, charts, images, and client-side components separately. A navigation timeout is different from a JavaScript readiness problem.
6. Preserve session-authenticated pages
EVO states that conversion runs in a new session, separate from the ASP.NET application session. Cookies and session values available to the app request therefore may not exist during conversion.
- Generate the final HTML inside the authenticated application session.
- Convert that HTML string through the EVO client.
- Make every stylesheet, image, font, and script referenced by that HTML reachable from the server.
- If the page requires bearer authentication, configure the version-matched header or cookie option, or expose a short-lived authorized resource.
Converting a URL is simpler for public pages. Converting an HTML string gives you control over session-derived content, but you must provide a base URL or absolute resource references.
7. Remove the demo warning
A watermark or demo warning is a licensing configuration issue. Set the purchased key on every relevant converter or document object, ensure the key is loaded in the platform project that performs conversion, and search the solution for code that later assigns a demo key. Log the selected package and key-source path without logging the secret itself.
8. Handle version and platform mismatches
- Check the resolved assembly version, target framework, CPU architecture, and platform project.
- Use the namespace shown by that exact package’s documentation.
- Do not assume a Xamarin.Forms shared project can call a platform-only API without a platform implementation.
- Keep server and client versions compatible according to EVO’s release documentation.
- If upgrading to EVO PDF Next, compare rendering defaults and API names before changing production settings.
9. A repeatable troubleshooting checklist
- Capture the complete exception and identify whether it occurs during connection, navigation, resource loading, script execution, output writing, or licensing.
- Record the Xamarin.Forms target, platform project, EVO package, assembly version, server location, host, port, and endpoint type.
- Convert plain HTML with no external resources.
- Convert a public URL.
- Add external CSS and images.
- Add authentication and session-derived content.
- Add JavaScript and asynchronous data.
- Adjust viewer width, page size, orientation, and fit behavior.
- Verify the license key on every converter/document object.
- Preserve the smallest failing reproduction for EVO support.
10. Performance, reliability, and cost considerations
- Use the shortest conversion delay that consistently includes required content.
- Reuse stable HTML and assets where possible, but avoid stale authenticated data.
- Keep navigation timeouts long enough for real network conditions; the legacy reference lists 60 seconds, which is not a universal value for every release.
- Measure server CPU, memory, disk space, and concurrent conversions in your deployment environment; the supplied EVO materials do not establish a universal throughput benchmark.
- Prefer a local TCP service when low network latency and controlled deployment matter; prefer a web-service endpoint when the converter must live behind a separate reachable URL and authentication boundary.
- For licensing cost, use the EVO license terms for the exact package and deployment model. Do not infer pricing from a different EVO generation.
11. Or skip the browser setup
If your actual goal is a screenshot or PDF of a web page rather than an embedded Xamarin conversion pipeline, ScreenshotNeo provides a hosted API. Cookie and consent banners are accepted and removed before capture, along with more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. It also provides an MCP server for AI agents and supports PDF output.
See the ScreenshotNeo API documentation for all options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes full-page capture, element selectors, dark mode, device presets, retina scale, custom CSS and JavaScript, waits, request blocking, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, bulk capture, usage data, and PDF controls. Plans include 1,000 free screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
12. FAQ
Does Xamarin.Forms itself perform the PDF conversion?
No. The Xamarin-side EVO client communicates with the separately installed EVO PDF Server. Place integration code in the platform project that owns the runtime connection.
Why does localhost work on my computer but fail on a phone?
Loopback is evaluated from the process making the connection. A phone’s loopback address is generally the phone, so use a reachable server address and allow the route through the firewall.
Should I increase the delay for every page?
No. Use a delay only when asynchronous content needs it. Static pages can use automatic behavior or no delay when supported by your package.
Can a larger paper size fix small text?
It can change scaling, but first inspect viewer width, fit-to-page settings, CSS widths, and the package generation’s rendering defaults.
When should I contact EVO support?
After reducing the issue to a minimal reproduction, provide the exact exception, package and assembly version, target platform, server version, host and port configuration, and a minimal HTML or URL.


