XmlRpcCore 4.0.0.4

dotnet add package XmlRpcCore --version 4.0.0.4
                    
NuGet\Install-Package XmlRpcCore -Version 4.0.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XmlRpcCore" Version="4.0.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XmlRpcCore" Version="4.0.0.4" />
                    
Directory.Packages.props
<PackageReference Include="XmlRpcCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XmlRpcCore --version 4.0.0.4
                    
#r "nuget: XmlRpcCore, 4.0.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XmlRpcCore@4.0.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XmlRpcCore&version=4.0.0.4
                    
Install as a Cake Addin
#tool nuget:?package=XmlRpcCore&version=4.0.0.4
                    
Install as a Cake Tool

XmlRpcCore

Build status
XmlRpcCore NuGet-Release
NuGet Downloads

Introduction

XmlRpcCore is a small, modernized XML-RPC client and serializer library compatible with .NET Standard 2.0 and later. The library favors modern .NET patterns:

  • Generic collections (List<object>, Dictionary<string, object>) instead of legacy non-generic collections.
  • DI-friendly serializers/deserializers (IXmlRpcSerializer).
  • Async streaming request/response APIs to avoid intermediate allocations.
  • Extensible mapping from XML-RPC values to POCOs via IObjectMapper.

This README shows current usage examples and a migration guide from legacy code (3.x and XmlRpcCs).

Namespace and breaking-change note

Public types you will commonly use are:

  • XmlRpcCore.XmlRpcRequest / XmlRpcCore.XmlRpcResponse
  • XmlRpcCore.IXmlRpcSerializer (serializer abstraction)
  • XmlRpcCore.XmlRpcNetSerializer (default serializer)
  • XmlRpcCore.XmlRpcClient (modern, DI-friendly client)
  • XmlRpcCore.ObjectMapper (default POCO mapper)

Breaking / migration notes:

  • There is an [Obsolete] constructor on XmlRpcRequest that accepts ArrayList kept only for transition. Prefer List<object> / Dictionary<string, object>.

Quickstart (copy/paste-ready)

A minimal example showing the typical call flow (includes required usings):

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using XmlRpcCore;

class Program
{
    static async Task Main()
    {
        var httpClient = new HttpClient();
        var request = new XmlRpcRequest("demo.sum", new List<object> { 4, 5 });
        var response = await httpClient.PostAsXmlRpcAsync("https://example.com/rpc", request);
        Console.WriteLine(response.Value);
    }
}

DI + HttpClientFactory example

Register the serializer, mapper and typed client using IServiceCollection so you can consume a typed XmlRpcClient with IHttpClientFactory integration:

using Microsoft.Extensions.DependencyInjection;
using XmlRpcCore;

var services = new ServiceCollection();

// register defaults
services.AddSingleton<IXmlRpcSerializer, XmlRpcNetSerializer>();
services.AddSingleton<IObjectMapper, ObjectMapper>();

// register typed client; AddHttpClient will supply HttpClient in constructor
services.AddHttpClient<XmlRpcClient>();

var provider = services.BuildServiceProvider();
var xmlClient = provider.GetRequiredService<XmlRpcClient>();

// use xmlClient.InvokeAsync<T>(url, request)

Streaming & cancellation example

Use the async stream APIs to avoid intermediate string allocations and to support cancellation:

using System.IO;
using System.Threading;
using XmlRpcCore;

var serializer = new XmlRpcNetSerializer();
var request = new XmlRpcRequest("demo.heavy", new List<object> { /* large payload */ });
using var ms = new MemoryStream();

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
await serializer.SerializeRequestAsync(request, ms, cts.Token);
ms.Position = 0;
var response = await serializer.DeserializeResponseAsync(ms, cts.Token);

Mapping caveats & System.Text.Json behavior

The default ObjectMapper uses System.Text.Json internally to map dictionary-shaped XML-RPC results into POCOs and back. A few important notes:

  • Nested objects and arrays are handled: the mapper converts JsonElement trees into plain CLR objects (integers, longs, doubles, strings, DateTime, List<object>, Dictionary<string, object>).
  • Numeric types may be int or long depending on value magnitude; code deserializing dictionary values should be resilient to long vs int (tests include helpers to convert when necessary).
  • Enums are mapped from strings when possible (default JsonStringEnumConverter behavior).
  • If you need tighter control or better performance for hot paths, consider implementing a reflection-based IObjectMapper and registering it in DI.

Security / XXE and hardening defaults

XmlRpcCore uses safe defaults to mitigate XXE and XML-based DoS attacks:

  • DTD processing is disabled by default and XmlResolver is not used.
  • A maximum element depth (MaxDepth, default 128) is enforced during parsing.
  • XmlRpcOptions exposes additional limits: MaxCharactersInDocument and MaxCharactersFromEntities. These are applied when supported by the runtime.

To tune settings for your application, set XmlRpcSettingsManager.Options at startup (example below). Only enable DTDs or an XmlResolver if you fully understand the security implications.

XmlRpcSettingsManager.Options = new XmlRpcOptions
{
    MaxDepth = 256,
    MaxCharactersInDocument = 50_000_000,
    MaxCharactersFromEntities = 2_000_000,
    AllowDtd = false,
    AllowXmlResolver = false
};

Notes

  • Changing Options affects all deserializers that use the shared settings. Set before handling untrusted input.
  • Only change AllowDtd/AllowXmlResolver if you fully understand the security implications.

Migration guide (legacy → modern)

If you previously used ArrayList/Hashtable or singleton serializers, follow these steps to migrate safely:

  • Replace ArrayList inputs with List<object> and Hashtable with Dictionary<string, object>.

Legacy code example:

// legacy
ArrayList args = new ArrayList();
args.Add("hello");
Hashtable map = new Hashtable();
map["a"] = 1;

Modern replacement:

var args = new List<object> { "hello" };
var map = new Dictionary<string, object> { ["a"] = 1 };
  • Use the DI-friendly IXmlRpcSerializer instead of singletons. Pass a serializer into XmlRpcClient or to XmlRpcRequest constructors when you need custom behavior.

  • Replace XmlRpcRequestSerializer.Singleton or XmlRpcResponseSerializer.Singleton calls by constructing an instance or registering one in DI.

Breaking changes

  • Legacy non-generic collections support has been removed from the core serialization pipeline. The codebase still ships a marked [Obsolete] constructor on XmlRpcRequest that accepts ArrayList as a transition, but you should migrate to generic collections.
  • The library now prefers modern APIs and async streaming patterns; some convenience synchronous APIs may still exist for compatibility.

Error handling

There are typed exceptions to help diagnosing issues:

  • XmlRpcProtocolException � parsing/format errors in XML.
  • XmlRpcTransportException � transport or unexpected deserialization errors.
  • XmlRpcException � represents an XML-RPC fault (faultCode/faultString).

Testing

The repository includes unit tests covering serialization, deserialization, streaming, mapping, and client behaviors. Run them with:

dotnet test XmlRpcCore.Tests/XmlRpcCore.Tests.csproj

Performance and tuning

  • Use the stream-based async APIs to avoid intermediate string allocations in high-throughput scenarios.
  • Swap the ObjectMapper for a reflection-based mapper if JSON round-trips are too costly for your workload.
  • Configure JsonSerializerOptions or provide a custom IObjectMapper to control mapping behavior.

Contributing

Contributions are welcome. Please follow the existing project style and add unit tests for new behaviors. Open issues or PRs on the project GitHub repository.

License

XmlRpcCore is under the BSD license. See: LICENSE.

References

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.