Raptor21.SAP.RFC 0.1.0

dotnet add package Raptor21.SAP.RFC --version 0.1.0
                    
NuGet\Install-Package Raptor21.SAP.RFC -Version 0.1.0
                    
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="Raptor21.SAP.RFC" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Raptor21.SAP.RFC" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Raptor21.SAP.RFC" />
                    
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 Raptor21.SAP.RFC --version 0.1.0
                    
#r "nuget: Raptor21.SAP.RFC, 0.1.0"
                    
#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 Raptor21.SAP.RFC@0.1.0
                    
#: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=Raptor21.SAP.RFC&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Raptor21.SAP.RFC&version=0.1.0
                    
Install as a Cake Tool

Raptor21.SAP.RFC

Typed, allocation-conscious access to SAP tables from .NET.

A class per table is written into your project — ordinary, readable, committed source, the same bargain as adding a service reference. Field names and types are then checked by the compiler, and nothing on the read path uses reflection.

var customers = await sap.From<Kna1>()
    .Where(x => x.Land1 == "TR" && x.Erdat >= new DateOnly(2024, 1, 1))
    .Select(x => new { x.Kunnr, x.Name1, x.Ort01, x.Erdat })
    .Take(5)
    .ToListAsync(cancellationToken);

Where becomes SAP's OPTIONS clause and Select its field list, so filtering and projection happen in SAP rather than after the rows arrive. An expression SAP cannot express throws while the query is built — never silently, and never by quietly reading the whole table.

What it does

  • Server-side filtering. The predicate, the projection and the row limit are evaluated in SAP.
  • Conversion exits. ALPHA and NUMC padding are applied to filters, so a query against a customer number finds the row instead of silently finding none.
  • Generated entities. The scaffolder reads the ABAP Data Dictionary and writes strongly typed classes, carrying the field descriptions SAP itself holds.
  • Streaming. Large result sets are paged and surfaced one row at a time, so a full table never has to fit in memory.
  • Transport-agnostic core. The SOAP RFC endpoint is the first transport; the abstraction is shaped so a native SAP NetWeaver RFC transport can be added without changing calling code.

What it does not do yet

  • The native (NetWeaver RFC SDK) transport is declared but not implemented.
  • Only reading. Function modules that change data are not exposed.
  • Currency scaling (TCURX) is not applied, so an amount in a currency with other than two decimals reads wrongly. Conversion exits that depend on the system's customising are refused rather than guessed.
  • The test suite covers the conversion rules and nothing that needs a system yet.

Requirements

  • .NET 10
  • A SAP system with the generic SOAP RFC endpoint (/sap/bc/soap/rfc) active
  • A user with S_RFC authorisation for the function modules used
  • For table reads, one of RFC_READ_TABLE, /BODS/RFC_READ_TABLE2 or /SAPDS/RFC_READ_TABLE2

The RFC_READ_TABLE2 variants are strongly preferred: the classic function truncates rows at a few hundred characters, while RFC_READ_TABLE2 selects an output buffer up to 30 000 characters wide and can return wide tables in a single call. Which variants a system has differs from system to system and cannot be inferred from the product, so it is discovered once and remembered per destination.

Configuration

Connections are named, following SAP's own RFC destination concept. The host owns the HttpClient; this package never creates one and never holds an address or a credential.

services.AddSapRfc(options =>
{
    options.AddDestination("PRD", destination =>
    {
        destination.Client  = "400";
        destination.Product = SapProduct.SapS4Hana;
    });

    options.DefaultDestination = "PRD";
});

// The address, the credentials and the timeout belong to the HttpClient, which the host already knows
// how to configure — with whatever authentication, proxy and certificate handling its environment needs.
services.AddHttpClient("PRD", client =>
{
    client.BaseAddress = new Uri(configuration["Sap:Prd:BaseAddress"]!);
    client.DefaultRequestHeaders.Authorization = BasicAuth(configuration);
});

Getting the classes

Either from Rider, with the companion plugin, or from the SapScaffold target this package installs:

<ItemGroup>
  <SapTable Include="KNA1" />
  <SapTable Include="TVKO" />
</ItemGroup>

<PropertyGroup>
  <SapSettingsFile>..\Config\sapSettings.json</SapSettingsFile>
  <SapSettingsProfile>SapSettings:S4Hana:Qa</SapSettingsProfile>
</PropertyGroup>
dotnet msbuild -t:SapScaffold

Scaffolding is something you run, not something a build does. No build contacts SAP and no build needs a credential — a fresh clone, a CI agent and a container image all compile the committed classes with no access to the system at all.

Property Default
SapScaffoldDirectory <project>\Sap Where the classes are written
SapScaffoldNamespace $(RootNamespace).Sap Namespace they are placed in
SapSchemaLanguage E Language the descriptions are read in
SapSettingsFile / SapSettingsProfile — Where to read the connection from
SapHost / SapUser / SapPassword / SapClient — The connection for one run; wins over the file

Full documentation: https://github.com/RaptorTwentyOne/Raptor21.SAP.RFC

Licence

MIT. See LICENSE in the repository.

Product 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. 
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.

Version Downloads Last Updated
0.1.0 179 8/7/2026
0.1.0-preview.3 76 8/7/2026
0.1.0-preview.2 82 8/6/2026
0.1.0-preview.1 74 8/4/2026