XmlRpcCore 4.0.0.4
dotnet add package XmlRpcCore --version 4.0.0.4
NuGet\Install-Package XmlRpcCore -Version 4.0.0.4
<PackageReference Include="XmlRpcCore" Version="4.0.0.4" />
<PackageVersion Include="XmlRpcCore" Version="4.0.0.4" />
<PackageReference Include="XmlRpcCore" />
paket add XmlRpcCore --version 4.0.0.4
#r "nuget: XmlRpcCore, 4.0.0.4"
#:package XmlRpcCore@4.0.0.4
#addin nuget:?package=XmlRpcCore&version=4.0.0.4
#tool nuget:?package=XmlRpcCore&version=4.0.0.4
XmlRpcCore
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.XmlRpcResponseXmlRpcCore.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 onXmlRpcRequestthat acceptsArrayListkept only for transition. PreferList<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
JsonElementtrees into plain CLR objects (integers, longs, doubles, strings, DateTime,List<object>,Dictionary<string, object>). - Numeric types may be
intorlongdepending on value magnitude; code deserializing dictionary values should be resilient tolongvsint(tests include helpers to convert when necessary). - Enums are mapped from strings when possible (default
JsonStringEnumConverterbehavior). - If you need tighter control or better performance for hot paths, consider implementing a reflection-based
IObjectMapperand 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
XmlResolveris not used. - A maximum element depth (
MaxDepth, default 128) is enforced during parsing. XmlRpcOptionsexposes additional limits:MaxCharactersInDocumentandMaxCharactersFromEntities. 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
Optionsaffects all deserializers that use the shared settings. Set before handling untrusted input. - Only change
AllowDtd/AllowXmlResolverif 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
ArrayListinputs withList<object>andHashtablewithDictionary<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
IXmlRpcSerializerinstead of singletons. Pass a serializer intoXmlRpcClientor toXmlRpcRequestconstructors when you need custom behavior.Replace
XmlRpcRequestSerializer.SingletonorXmlRpcResponseSerializer.Singletoncalls 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 onXmlRpcRequestthat acceptsArrayListas 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
ObjectMapperfor a reflection-based mapper if JSON round-trips are too costly for your workload. - Configure
JsonSerializerOptionsor provide a customIObjectMapperto 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
- XML-RPC spec: http://xmlrpc.org
- Original project: http://xmlrpccs.sourceforge.net/
| Product | Versions 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. |
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.11)
- System.Text.Json (>= 9.0.11)
-
.NETStandard 2.1
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.11)
- System.Text.Json (>= 9.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.