Centeva.AdamsInterface 2.0.0

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

Centeva.AdamsInterface

ADAMS API client library for .NET. Wraps the 43 operations the NRC ADAMS document management system exposes, so a consuming application can push and pull content without re-implementing the contract.

Supports Windows Authentication with Kerberos delegation, bearer tokens for OIDC, and a no-auth mode for local development.

Built With

Package Version Purpose
Ardalis.Result 10.1.0 Operation outcomes
FluentValidation 12.1.1 Request validation
Microsoft.Extensions.Http 8.0.1 IHttpClientFactory
Microsoft.AspNetCore.Http 2.3.0 IHttpContextAccessor for the auth strategies

Targets net8.0, net9.0 and net10.0.

Installation

dotnet add package Centeva.AdamsInterface

Configuration

{
  "Adams": {
    "BaseUri": "https://your-adams-server/adams/api/",
    "AuthMode": "Windows",
    "ValidateRequests": true
  }
}
Key Default Notes
BaseUri required Trailing slash matters: operation paths are resolved relative to it.
AuthMode Windows Windows, Bearer or None. An unrecognized value fails at startup.
ValidateRequests true Validates requests before sending. Turn off only if ADAMS accepts something the rules reject.
services.AddAdamsClient(configuration);

That reads Adams:AuthMode and wires the matching strategy, so moving an environment to OIDC is a configuration change rather than a code change. To decide in code instead:

services.AddAdamsClientCore(configuration)
        .AddBearerTokenAuthentication();   // or AddWindowsAuthentication / AddNoAuthentication

Usage

Inject IAdamsApiClient and call the operation you need. Everything returns Result<T> from Ardalis.Result.

public class DocumentService(IAdamsApiClient adams)
{
    public async Task<string> AddDraftAsync(string blobPath, CancellationToken ct)
    {
        var result = await adams.Document.AddNewDraft(new AddNewDraft.Request
        {
            DocumentPathAndFileName = blobPath,
            DocumentTitle = "RAI Response",
            SensitivityReviewCompleted = "Yes",
            SunsiDocumentSensitivity = Adams.NonSensitive,
            Availability = Adams.PubliclyAvailable
        }, ct);

        if (!result.IsSuccess)
        {
            // result.Status is Invalid for a request that broke its own rules, Error for
            // anything ADAMS refused. result.Errors carries the ADAMS message.
            throw new InvalidOperationException(string.Join("; ", result.Errors));
        }

        return result.Value.AccessionNumber;
    }
}

How outcomes map

Outcome Result
ADAMS accepted the call (responseCode 0) ResultStatus.Ok, payload in Value
The request broke its own validation rules ResultStatus.Invalid, fields in ValidationErrors, nothing sent
ADAMS answered with a non-zero responseCode ResultStatus.Error, ADAMS message in Errors
ADAMS answered with a non-success HTTP status ResultStatus.Error
No network, DNS failure, timeout throws

That last row is deliberate. A transport failure is infrastructure breakage rather than an answer from ADAMS; turning it into a Result would hide an outage and defeat any retry policy, which acts on exceptions.

Operations

IAdamsApiClient exposes four groups covering all 43 ADAMS operations.

Group Count Examples
Document 14 AddNewDraft, AddNewOfficialRecord, RetrieveProperties, UpdateProperties, CheckInNewVersion, SubmitToDpcForNormalProcessing, SubmitToDpcForImmediatePublicRelease, ChangeClass, Declare, permissions, Delete
Folder 8 AddNewFolder, FileIntoFolder, UpdateProperties, permissions, Delete
Package 12 AddNewPackage, FileIntoPackage, RetrieveProperties, UpdateProperties, DPC submission, Declare, permissions, Delete
ReferenceData 9 Availability, SUNSI sensitivity, document type, distribution list codes, author and addressee lookups, docket numbers

Every relative path lives in AdamsRoutes, which is the single source of truth for the route contract. A simulated ADAMS server should bind the same constants so the two cannot drift.

Authentication

IAuthenticationStrategy has three implementations, selected by Adams:AuthMode.

Windows (default, and what ADAMS requires today). Resolves the caller's WindowsIdentity from the HTTP context and wraps the call in WindowsIdentity.RunImpersonatedAsync so the Kerberos hop to ADAMS is made as them. Windows-only. Requires IIS with ASP.NET Impersonation and Kerberos delegation to reach a remote ADAMS.

Bearer, for OIDC and OAuth. The package sends tokens; it does not acquire them. Resolution order is a caller-supplied provider, then the inbound Authorization header, then an access_token claim:

services.AddAdamsClientCore(configuration)
        .AddBearerTokenAuthentication(async () => await myTokenService.GetAccessTokenAsync());

None, for local development against a simulated ADAMS.

Background jobs

Header pass-through cannot work outside an HTTP request, so code calling ADAMS from a background job under OIDC must supply a token provider, typically a client-credentials flow. There is no ambient identity to fall back on the way Windows authentication has.

Note the matching Windows behavior: with no HTTP context, the Windows strategy falls back to the process identity, so ADAMS calls from a background job act as the app pool account rather than a user.

Validation

Each request entity ships a FluentValidation Validator describing the ADAMS field contract. AddAdamsClientCore registers them and the client runs them before sending, so a malformed accession number is rejected locally rather than costing a round trip and coming back as an opaque response code.

Set Adams:ValidateRequests to false to bypass, which exists because these rules were written against observed ADAMS behavior rather than a published specification. If ADAMS accepts something they reject, a consumer should not have to wait for a package release.

Local development

The simulated ADAMS server that 1.x bundled into this package has been removed, so the client no longer drags ASP.NET Core MVC into your application or registers routes in it.

It is being rebuilt as Centeva.RpsSimulatedAdams, a standalone container. That is not published yet. Until it is, point development at whatever ADAMS stand-in you already run and turn authentication off against it:

{ "Adams": { "BaseUri": "http://localhost:9070/api/", "AuthMode": "None" } }

Document content

ADAMS reads document content itself; this client never sends bytes. AddNewDraft and AddNewOfficialRecord take DocumentPathAndFileName, which is a container-relative logical path inside the configured Azure Blob Storage container - for example /NRR/RAI App/EPID-12345/response.pdf. There is no scheme, host, container name or SAS token in it; ADAMS knows the account and container out of band and resolves the rest.

Write the file to storage before calling ADAMS.

Upload workflow

The order matters, because ADAMS resolves the content and the folder tree as it goes.

// 1. Put the file in storage where ADAMS can reach it.
await objectStorage.WriteAsync(StoragePath.Combine(destinationFolder, fileName), stream, ct);

// 2. Create the folder path, one segment at a time.
var folder = await adams.Folder.AddNewFolder(new AddNewFolder.Request
{
    ParentFolderPath = "/NRR/RAI App",
    NewFolderName = epid
}, ct);

// 3. Create a package, if the documents are to be released together.
var package = await adams.Package.AddNewPackage(new AddNewPackage.Request
{
    PackageTitle = title,
    Availability = Adams.PubliclyAvailable
}, ct);

// 4. Add the document, referencing the path written in step 1.
var document = await adams.Document.AddNewDraft(new AddNewDraft.Request
{
    DocumentPathAndFileName = $"{destinationFolder}/{fileName}",
    DocumentTitle = title,
    SensitivityReviewCompleted = "Yes",
    SunsiDocumentSensitivity = Adams.NonSensitive,
    Availability = Adams.PubliclyAvailable
}, ct);

// 5. File it into the package or the folder.
await adams.Package.FileIntoPackage(new FileIntoPackage.Request
{
    DocumentAccessionNumber = document.Value.AccessionNumber,
    PackageAccessionNumber = package.Value.AccessionNumber
}, ct);

// 6. Submit to DPC, if it should be released.
await adams.Package.SubmitToDpcForNormalProcessing(new SubmitToDpcForNormalProcessing.Request
{
    AccessionNumber = package.Value.AccessionNumber
}, ct);

Check IsSuccess on each step. The sequence is not transactional: a failure partway through leaves the folder, package and documents already created in ADAMS.

Running tests

dotnet test Centeva.AdamsInterface.slnx

Contributing

Branch from master, open a pull request. CI builds and tests against all three target frameworks. Releases are cut by publishing a GitHub Release tagged vX.Y.Z from master; the tag is the only source of the package version.

License

MIT. See LICENSE.

Platform compatibility

net8.0, net9.0 and net10.0. WindowsAuthenticationStrategy is Windows-only, as Kerberos impersonation has no cross-platform equivalent; the bearer and none strategies run anywhere.

Product 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 is compatible.  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 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
2.0.0 102 9/4/2026
1.0.1 175 7/15/2026 1.0.1 is deprecated because it has critical bugs.
1.0.0 169 5/28/2026 1.0.0 is deprecated because it has critical bugs.