Opacc.Client.CLI
0.4.0
dotnet tool install --global Opacc.Client.CLI --version 0.4.0
dotnet new tool-manifest
dotnet tool install --local Opacc.Client.CLI --version 0.4.0
#tool dotnet:?package=Opacc.Client.CLI&version=0.4.0
nuke :add-package Opacc.Client.CLI --version 0.4.0
Opacc.Client.CLI
Command-line tool for the Opacc.Client library. Currently provides the scaffold command, which introspects a live Opacc instance and generates ready-to-use C# model classes.
Installation
Local (development)
Run directly from the project directory without installing:
cd opacc-client/Opacc.Client.CLI
dotnet run -- <command> [options]
The -- separator is required — everything after it is passed to the CLI, not to dotnet run.
Global .NET tool
dotnet pack
dotnet tool install --global --add-source ./nupkg Opacc.Client.CLI
Once installed, the tool is available as opacc:
opacc scaffold [options]
Commands
scaffold
Connects to an Opacc instance, reads all Business Object metadata via GetInfoBo and GetInfoBoAttr, and writes one .cs file per BO into the output directory.
Options
| Option | Short | Required | Description |
|---|---|---|---|
--output <path> |
-o |
Yes | Directory where .cs files are written. Created if it does not exist. |
--url <url> |
-u |
Yes¹ | Opacc WebService endpoint URL. |
--client-id <id> |
Yes¹ | Opacc Mandant / Client ID (e.g. "1"). |
|
--app-id <name> |
Yes¹ | Application / Consumer name (appears in Opacc logs). | |
--user-id <id> |
Yes¹ | Opacc user ID used to authenticate. | |
--password <pwd> |
-p |
Yes¹ | Password for the given user. Accepts both plain text and the encrypted format Opacc uses internally. |
--bo <name> |
-b |
No | Scaffold a single BO (e.g. Addr). When omitted, all BOs are scaffolded. |
--namespace <ns> |
-n |
No | Namespace for the generated classes. When omitted, derived automatically (see below). |
--verbose |
-v |
No | Print each attribute's raw DataTypeCd, Format, and description before generating. Useful for diagnosing unexpected type mappings. |
¹ The five connection options don't have to be passed on the command line. Each one falls back to configuration (see Connection configuration below), so once you've set them up you only run opacc scaffold -o ./Models. A missing value is only an error if it can't be found in any source.
Connection configuration
Rather than repeating --url, --client-id, --app-id, --user-id and --password on every call, the tool resolves each value from the following sources. Higher in the list wins, so a command-line flag always overrides configuration:
- Command-line flag —
--url,--password, … - Environment variable —
Opacc__ServiceUrl,Opacc__DefaultPassword, … (double underscore = section separator) - User Secret —
dotnet user-secrets set "Opacc:DefaultPassword" "…" appsettings.jsonin the current working directory — anOpaccsection
This mirrors how EF Core resolves a Name=… connection string from the startup project's configuration.
Put the non-secret values in appsettings.json next to where you run the tool:
{
"Opacc": {
"ServiceUrl": "https://opacc.example.com/OXAS_ServiceBus",
"ClientId": "1",
"ApplicationId": "MyApp",
"DefaultUserId": "500"
}
}
Keep the password out of source control — supply it per environment instead:
# Development (from the Opacc.Client.CLI project folder, or your own project):
dotnet user-secrets set "Opacc:DefaultPassword" "<pwd>"
# CI / one-off runs:
# PowerShell: $env:Opacc__DefaultPassword = "<pwd>"
# bash: export Opacc__DefaultPassword="<pwd>"
The config keys match the OpaccClientOptions property names (ServiceUrl, ClientId, ApplicationId, DefaultUserId, DefaultPassword) — the same Opacc section your application binds via services.AddOpaccClient(configuration.GetSection("Opacc")), so the CLI and your app can share one config file.
Namespace resolution
The namespace is determined in this order:
- Explicit —
--namespace Opacc.Client.Modelsis used as-is. - Automatic — the tool walks up from the output directory to find the nearest
.csprojfile.- Reads
<RootNamespace>from that file, or falls back to the project filename without extension. - Appends the relative path from the project root to the output directory as additional segments.
- Reads
Example:
.csproj → opacc-client/Opacc.Client/Opacc.Client.csproj
RootNamespace = "Opacc.Client"
--output → opacc-client/Opacc.Client/Models
relative → Models
result → namespace Opacc.Client.Models;
The resolved namespace is printed before scaffolding begins so you can verify it before all files are written.
Examples
With connection details in appsettings.json + a user secret (recommended):
# one-time setup
dotnet user-secrets set "Opacc:DefaultPassword" "<pwd>"
# from then on — no credentials on the command line:
opacc scaffold --output "./Models"
opacc scaffold --output "./Models" --bo Addr --verbose
Scaffold a single BO for quick verification (all details on the command line):
dotnet run -- scaffold \
--url "YourOpaccWebserviceUrl" \
--client-id "1" \
--app-id "MyApp" \
--user-id "500" \
--password "..." \
--bo Addr \
--output "./Models" \
--verbose
Scaffold all BOs into the library's Models folder:
dotnet run -- scaffold \
--url "YourOpaccWebserviceUrl" \
--client-id "1" \
--app-id "MyApp" \
--user-id "500" \
--password "..." \
--output "C:/Projects/opacc-client/Opacc.Client/Models"
Override namespace explicitly:
dotnet run -- scaffold ... \
--output "./out" \
--namespace "MyCompany.Erp.Models"
Generated output
Each BO produces one file, e.g. Addr.cs:
using Opacc.Client.Attributes;
using Opacc.Client.Enums;
namespace Opacc.Client.Models;
[Bo("Addr")]
[BoIndex(1)]
public class Addr
{
public int Number { get; set; }
public string FullName { get; set; } = "";
public string City { get; set; } = "";
[BoProperty("Addr.SomeDate", OpaccDataType.Date)]
public DateTime SomeDate { get; set; }
/// <summary>Customer BoId reference</summary>
[BoProperty("Addr.CustBoId")]
public string CustBoId { get; set; } = "";
}
Attribute rules
| Condition | Generated attribute |
|---|---|
Expression matches BoName.PropertyName by convention |
None — property name alone is sufficient |
Expression differs from convention (e.g. cross-BO like Cust.Remark) |
[BoProperty("Cust.Remark")] |
Date field (DataTypeCd = D) |
[BoProperty("...", OpaccDataType.Date)] |
| Date field that also follows convention | [BoProperty("Addr.SomeDate", OpaccDataType.Date)] |
Data type mapping
Opacc DataTypeCd |
Format example | C# type |
|---|---|---|
A |
50 |
string |
N |
8.0 |
int |
N |
8.2 |
decimal |
D |
— | DateTime + OpaccDataType.Date |
B |
— | bool |
T |
— | DateTime |
| anything else | — | string (safe fallback) |
Numeric format "8.0" means 8 digits, 0 decimal places → int. Format "8.2" means 2 decimal places → decimal.
How it works internally
scaffold
│
├── Biz.GetInfoBo()
│ → returns all BO names (column: "Bo")
│
└── for each BO:
Biz.GetInfoBoAttr(boName)
→ returns all attributes (columns: "BoAttr", "DataTypeCd", "Format", ...)
→ TypeMapper maps DataTypeCd + Format to C# type
→ ModelGenerator emits the .cs file
Both service calls go through IOpaccTransport.SendRawAsync, the same authenticated WCF session pool used by the main library. Sessions are created on first use and reused for the duration of the command.
Troubleshooting
namespace Models; instead of a proper namespace
The tool could not find a .csproj above the output directory. Either move the output inside a project folder, or pass --namespace explicitly.
BO scaffolded with 0 attributes — skipped
GetInfoBoAttr returned an empty response for that BO. This is normal for internal system BOs that have no accessible attributes.
FaultException on a specific attribute
The generated model contains a property that no longer exists in this Opacc version. Remove the property or mark it with a custom ignore attribute. Run --verbose to see the raw attribute list and compare against your Opacc instance.
Unknown column names in verbose output
The --verbose flag prints DataTypeCd/Format for each attribute. If these look unexpected, the OpaccInfoClient has a DumpColumns() helper you can call in code to print the raw response column names for diagnostics.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|