RfcClient 0.1.1
See the version list below for details.
dotnet add package RfcClient --version 0.1.1
NuGet\Install-Package RfcClient -Version 0.1.1
<PackageReference Include="RfcClient" Version="0.1.1" />
<PackageVersion Include="RfcClient" Version="0.1.1" />
<PackageReference Include="RfcClient" />
paket add RfcClient --version 0.1.1
#r "nuget: RfcClient, 0.1.1"
#:package RfcClient@0.1.1
#addin nuget:?package=RfcClient&version=0.1.1
#tool nuget:?package=RfcClient&version=0.1.1
RfcClient
RfcClient is a DI-friendly SAP RFC client wrapper for SAP .NET Connector.
It targets .NET 10.0. The library supports multiple SAP RFC connection configs, request-scoped ConfigId switching, typed request/response mapping, and connection/invocation monitoring hooks.
Additional documentation:
Features
- Multiple SAP RFC connection configs by
ConfigId - Default config selection through
IsDefault - ASP.NET Core / generic host dependency injection support
- Request-scoped RFC session switching through
IRfcClient.ConfigId - Typed RFC input/output mapping with
[Table]and[Column] - Connection and invocation monitoring extension points
- SAP NCo runtime files included from project
libs
Installation
Install the NuGet package:
dotnet add package RfcClient
The package targets net10.0.
Configuration
Add RFC connection configs to appsettings.json:
{
"RfcConnectionConfigs": [
{
"ConfigId": "Sap",
"IsDefault": true,
"ConnectionString": "ApplicationServer=192.168.1.65;SystemNumber=00;SystemId=DEV;Client=800;UserName=DEVUSER;Password=******;Language=ZH;PoolSize=5;MaxPoolSize=10;ConnectionTimeout=30;CommunicationTimeout=60;"
},
{
"ConfigId": "Sap.JSY",
"IsDefault": false,
"ConnectionString": "MessageServerHost=192.168.1.65;MessageServerService=3600;SystemId=DEV;Client=800;UserName=DEVUSER;Password=******;Language=ZH;PoolSize=5;MaxPoolSize=10;"
}
]
}
Supported ConnectionString parameters map to RfcConfigParameter:
ApplicationServer
Server
SystemNumber
SystemId
Client
UserName
User ID
UserId
Password
Language
PoolSize
MaxPoolSize
Max Pool Size
ConnectionTimeout
CommunicationTimeout
MessageServerHost
MessageServerService
MessageServerPort
ApplicationServer / Server is used for direct application server connections. MessageServerHost is used for message server connections.
Register Services
Register the client with IServiceCollection. Pass the configuration explicitly, or let it auto-resolve IConfiguration from the DI container:
using RfcClient;
// Option 1: pass configuration explicitly
builder.Services.AddRfcClient(builder.Configuration);
// Option 2: auto-resolve IConfiguration from the DI container
builder.Services.AddRfcClient();
If your SAP RFC settings live under a section:
builder.Services.AddRfcClient(
builder.Configuration.GetSection("Rfc"));
Programmatic registration is also supported:
using RfcClient;
builder.Services.AddRfcClient(options =>
{
options.RfcConnectionConfigs.Add(new RfcConnectionConfig
{
ConfigId = "Sap",
IsDefault = true,
ConnectionString = "ApplicationServer=192.168.1.65;SystemNumber=00;Client=800;UserName=DEVUSER;Password=******;"
});
});
Define RFC Models
Use [Table] on the request type to declare the RFC function name. Use [Column] on properties to map SAP RFC parameter names.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("ZFM_MM039")]
public class SupplyDemandRequest
{
[Required]
[Column("IV_MATNR")]
public string MaterialCode { get; set; } = string.Empty;
[Required]
[Column("IV_BUKRS")]
public string CompanyCode { get; set; } = string.Empty;
[Column("IV_WERKS")]
public string PlantCode { get; set; } = string.Empty;
[Required]
[Column("IV_SYSTEM")]
public string Source { get; set; } = string.Empty;
}
using System.ComponentModel.DataAnnotations.Schema;
public class SupplyDemandResponse
{
[Column("EV_STATUS")]
public string Status { get; set; } = string.Empty;
[Column("EV_MESSAGE")]
public string Message { get; set; } = string.Empty;
[Column("ET_DATA")]
public SupplyDemandRow[] Rows { get; set; } = Array.Empty<SupplyDemandRow>();
}
public class SupplyDemandRow
{
[Column("MATNR")]
public string MaterialCode { get; set; } = string.Empty;
[Column("WERKS")]
public string PlantCode { get; set; } = string.Empty;
[Column("BDMNG")]
public decimal Quantity { get; set; }
}
Basic Call
Inject IRfcClient and invoke the RFC with typed request/response models:
using RfcClient.Abstractions;
public class SupplyDemandService
{
private readonly IRfcClient _rfcClient;
public SupplyDemandService(IRfcClient rfcClient)
{
_rfcClient = rfcClient;
}
public SupplyDemandResponse Query()
{
var request = new SupplyDemandRequest
{
MaterialCode = "B0505XT-1WR3",
CompanyCode = "1100",
PlantCode = "",
Source = "C"
};
return _rfcClient.Invoke<SupplyDemandRequest, SupplyDemandResponse>(request);
}
}
IRfcClient exposes a scoped ConfigId property. If ConfigId is empty, the client uses the config marked with IsDefault=true. If no config is marked as default, it uses the first item in RfcConnectionConfigs.
Switch ConfigId Per Request
Set IRfcClient.ConfigId inside the current request scope. After that, all IRfcClient calls in the same scope use that config automatically.
Example middleware:
using RfcClient.Abstractions;
app.Use(async (context, next) =>
{
var rfcClient = context.RequestServices.GetRequiredService<IRfcClient>();
var configId = context.Request.Headers["X-Sap-Rfc-ConfigId"].FirstOrDefault();
if (!string.IsNullOrWhiteSpace(configId))
{
rfcClient.ConfigId = configId;
}
await next();
});
Example controller:
using Microsoft.AspNetCore.Mvc;
using RfcClient.Abstractions;
[ApiController]
[Route("api/supply-demand")]
public class SupplyDemandController : ControllerBase
{
private readonly IRfcClient _rfcClient;
public SupplyDemandController(IRfcClient rfcClient)
{
_rfcClient = rfcClient;
}
[HttpPost]
public ActionResult<SupplyDemandResponse> Query(SupplyDemandRequest request)
{
var response = _rfcClient.Invoke<SupplyDemandRequest, SupplyDemandResponse>(request);
return Ok(response);
}
}
Calling the API with a header switches the SAP RFC config for that request:
X-Sap-Rfc-ConfigId: Sap.JSY
Call With Explicit ConfigId
Set IRfcClient.ConfigId before invoking when you need explicit control over the RFC config:
using RfcClient.Abstractions;
public class ManualRfcService
{
private readonly IRfcClient _rfcClient;
public ManualRfcService(IRfcClient rfcClient)
{
_rfcClient = rfcClient;
}
public SupplyDemandResponse QueryWithJsy(SupplyDemandRequest request)
{
_rfcClient.ConfigId = "Sap.JSY";
return _rfcClient.Invoke<SupplyDemandRequest, SupplyDemandResponse>(request);
}
}
Set ConfigId back to an empty string to return to the default configured SAP RFC connection in the same scope.
Monitor Connections And Calls
Implement IRfcConnectionMonitor to observe resolved destinations and RFC invocations:
using Microsoft.Extensions.Logging;
using RfcClient;
using RfcClient.Abstractions;
public class LoggingRfcConnectionMonitor : IRfcConnectionMonitor
{
private readonly ILogger<LoggingRfcConnectionMonitor> _logger;
public LoggingRfcConnectionMonitor(ILogger<LoggingRfcConnectionMonitor> logger)
{
_logger = logger;
}
public void DestinationResolved(RfcDestinationResolvedContext context)
{
_logger.LogInformation(
"SAP RFC destination resolved. ConfigId={ConfigId}, ForceNew={ForceNew}, PoolSize={PoolSize}, MaxPoolSize={MaxPoolSize}",
context.ConfigId,
context.ForceNew,
context.ConfigParameter.PoolSize,
context.ConfigParameter.MaxPoolSize);
}
public void InvocationStarted(RfcInvocationContext context)
{
_logger.LogInformation(
"SAP RFC invocation started. ConfigId={ConfigId}, Function={Function}",
context.ConfigId,
context.FunctionName);
}
public void InvocationSucceeded(RfcInvocationContext context)
{
_logger.LogInformation(
"SAP RFC invocation succeeded. ConfigId={ConfigId}, Function={Function}, Elapsed={ElapsedMs}ms",
context.ConfigId,
context.FunctionName,
context.Elapsed.TotalMilliseconds);
}
public void InvocationFailed(RfcInvocationContext context, Exception exception)
{
_logger.LogError(
exception,
"SAP RFC invocation failed. ConfigId={ConfigId}, Function={Function}, Elapsed={ElapsedMs}ms",
context.ConfigId,
context.FunctionName,
context.Elapsed.TotalMilliseconds);
}
}
Register the monitor before or after AddRfcClient:
using RfcClient.Abstractions;
builder.Services.AddSingleton<IRfcConnectionMonitor, LoggingRfcConnectionMonitor>();
builder.Services.AddRfcClient(builder.Configuration);
Do not log passwords or full connection strings.
Runtime Files
The project expects SAP NCo runtime files under the libs folder:
libs/cpc4n.dll
libs/ijwhost.dll
libs/sapnco.dll
libs/sapnco_utils.dll
During build, these files are copied to the output root directory alongside RfcClient.dll. They are also included in the NuGet package under lib/net10.0/.
Configuration options: the library exposes two timing options in RfcOptions:
CleanupInterval(default00:05:00): how often the client checks for idle destinations to cleanup.DestinationIdleTimeout(default00:10:00): how long a destination can stay unused before being removed from the cache.
You can set these in appsettings.json or via code when registering the services.
XML Documentation
The library generates an XML documentation file (RfcClient.xml) alongside the assembly in the build output. IDEs such as Visual Studio and JetBrains Rider automatically pick it up to provide inline Chinese and English descriptions for public types and members.
Build And Pack
dotnet build .\RfcClient.sln
dotnet pack .\RfcClient.csproj -c Release
The package is generated under:
bin/Release/RfcClient.0.1.0.nupkg
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.9)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.12 | 87 | 8/5/2026 |
| 1.0.11 | 78 | 7/24/2026 |
| 1.0.10 | 74 | 7/24/2026 |
| 1.0.9 | 77 | 7/22/2026 |
| 1.0.8 | 83 | 7/21/2026 |
| 1.0.7 | 79 | 7/20/2026 |
| 1.0.6 | 75 | 7/15/2026 |
| 1.0.5 | 81 | 7/15/2026 |
| 1.0.4 | 73 | 7/15/2026 |
| 1.0.3 | 81 | 7/14/2026 |
| 1.0.2 | 84 | 7/13/2026 |
| 1.0.1 | 75 | 7/13/2026 |
| 1.0.0 | 88 | 7/11/2026 |
| 0.1.1 | 89 | 7/9/2026 |
| 0.1.0 | 84 | 7/9/2026 |