Centeva.AdamsInterface
1.0.0
Prefix Reserved
dotnet add package Centeva.AdamsInterface --version 1.0.0
NuGet\Install-Package Centeva.AdamsInterface -Version 1.0.0
<PackageReference Include="Centeva.AdamsInterface" Version="1.0.0" />
<PackageVersion Include="Centeva.AdamsInterface" Version="1.0.0" />
<PackageReference Include="Centeva.AdamsInterface" />
paket add Centeva.AdamsInterface --version 1.0.0
#r "nuget: Centeva.AdamsInterface, 1.0.0"
#:package Centeva.AdamsInterface@1.0.0
#addin nuget:?package=Centeva.AdamsInterface&version=1.0.0
#tool nuget:?package=Centeva.AdamsInterface&version=1.0.0
Centeva.AdamsInterface
ADAMS API client library for .NET - Supports Windows Authentication, Bearer Token (OIDC), and pluggable authentication strategies for integrating with ADAMS document management systems.
Built With
- .NET 8.0, .NET 9.0 & .NET 10.0
- Mediator 3.0.2 - CQRS command/query pattern (replaces MediatR for licensing)
- FluentValidation 11.11.0 - Request validation with automatic pipeline integration
- ASP.NET Core - HTTP client and authentication infrastructure
Getting Started
Installation
dotnet add package Centeva.AdamsInterface
Basic Configuration
Windows Authentication (Default)
services.AddAdamsClient(configuration);
Bearer Token / OIDC Authentication
services.AddAdamsClientCore(configuration)
.AddBearerTokenAuthentication();
Custom Token Provider
services.AddAdamsClientCore(configuration)
.AddBearerTokenAuthentication(async () =>
{
// Your custom token acquisition logic
return await GetAccessTokenAsync();
});
No Authentication (Testing/Development)
services.AddAdamsClientCore(configuration)
.AddNoAuthentication();
With Mediator Commands
services.AddAdamsClientWithMediator(configuration); // Includes Windows Auth + Mediator
// or
services.AddAdamsClient(configuration)
.AddAdamsMediatorHandlers();
Configuration
Add ADAMS configuration to your appsettings.json:
{
"AdamsApi": {
"BaseUrl": "https://your-adams-server/adams/api",
"Timeout": 120
}
}
Usage Patterns
This package supports three integration patterns depending on your application architecture. Choose the pattern that best fits your needs:
Pattern 1: Direct API Client (Recommended)
Use when: Building any application - controllers, services, background jobs
Inject IAdamsApiClient and call methods directly. This is the simplest, most maintainable approach.
Configuration:
services.AddAdamsClient(configuration); // Registers IAdamsApiClient with Windows Auth
In ASP.NET Core Controllers:
using Centeva.AdamsInterface.Entities.Document;
using Centeva.AdamsInterface.Interfaces;
using Microsoft.AspNetCore.Mvc;
public class AdamsDocumentController : ControllerBase
{
private readonly IAdamsApiClient _adamsClient;
public AdamsDocumentController(IAdamsApiClient adamsClient)
{
_adamsClient = adamsClient;
}
[HttpPost("AddNewDraft")]
public Task<AddNewDraft.Response> AddNewDraft([FromBody] AddNewDraft.Request request)
{
return _adamsClient.Document.AddNewDraft(request, HttpContext.RequestAborted);
}
[HttpGet("SubmitToDpc")]
public Task<SubmitToDpcForNormalProcessing.Response> SubmitToDpc(string accessionNumber)
{
var request = new SubmitToDpcForNormalProcessing.Request
{
AccessionNumber = accessionNumber
};
return _adamsClient.Document.SubmitToDpcForNormalProcessing(request, HttpContext.RequestAborted);
}
}
In Application Services:
using Centeva.AdamsInterface.Interfaces;
public class DocumentService
{
private readonly IAdamsApiClient _adamsClient;
public DocumentService(IAdamsApiClient adamsClient)
{
_adamsClient = adamsClient;
}
public async Task<string> CreateDocumentAsync(string title, string fileUrl)
{
var response = await _adamsClient.Document.AddNewDraft(new AddNewDraft.Request
{
DocumentTitle = title,
DocumentPathAndFileName = fileUrl,
Availability = "Public",
SensitivityReviewCompleted = "Yes",
SunsiDocumentSensitivity = "Not Sensitive"
}, CancellationToken.None);
return response.AccessionNumber;
}
}
Benefits:
- ✅ Simplest approach - no mediator framework required
- ✅ Direct control flow - easy to debug and trace
- ✅ Zero abstraction overhead
- ✅ Entity Request objects have built-in FluentValidation
- ✅ No command wrapper duplication across consuming apps
Pattern 2: Mediator Commands (For CQRS Architectures)
Use when: Your application uses Mediator.SourceGenerator and you want CQRS pattern consistency
Use the package's 43 built-in Mediator command handlers to integrate with your existing Mediator pipeline.
Configuration:
services.AddMediator(); // Your app's Mediator configuration
services.AddAdamsMediatorHandlers(); // Registers package's command handlers
Usage:
using Centeva.AdamsInterface.Commands.Document;
using Centeva.AdamsInterface.Entities.Document;
public class DocumentController : ControllerBase
{
private readonly Mediator.IMediator _mediator;
public DocumentController(Mediator.IMediator mediator)
{
_mediator = mediator;
}
[HttpPost("AddNewDraft")]
public Task<AddNewDraft.Response> AddNewDraft([FromBody] AddNewDraft.Request request)
{
return _mediator.Send(new AddNewDraftCommand.Request(request));
}
}
Benefits:
- ✅ Integrates with existing Mediator pipeline and behaviors
- ✅ Reuses package's FluentValidation rules automatically
- ✅ Consistent CQRS pattern throughout your application
Pattern 3: Custom Orchestration Commands
Use when: Creating application-specific workflows that coordinate multiple ADAMS operations or integrate with your domain logic
For complex workflows that go beyond simple API calls, create custom commands that orchestrate multiple operations.
using Centeva.AdamsInterface.Interfaces;
using MediatR; // or Mediator
public class UploadDocumentPackageCommand : IRequest<UploadResult>
{
public int DocumentId { get; set; }
public List<FileInfo> Files { get; set; }
public string PackageTitle { get; set; }
}
public class Handler : IRequestHandler<UploadDocumentPackageCommand, UploadResult>
{
private readonly IAdamsApiClient _adamsClient;
private readonly IRepository _repository;
private readonly IStorageService _storage;
public async Task<UploadResult> Handle(UploadDocumentPackageCommand command, CancellationToken ct)
{
// 1. Your business logic: Upload files to storage
var fileUrls = await _storage.UploadFilesAsync(command.Files);
// 2. ADAMS API: Create package
var packageResponse = await _adamsClient.Package.AddNewPackage(new AddNewPackage.Request
{
PackageTitle = command.PackageTitle,
Availability = "Public"
}, ct);
// 3. ADAMS API: Add documents to package
foreach (var url in fileUrls)
{
var docResponse = await _adamsClient.Document.AddNewDraft(new AddNewDraft.Request
{
DocumentPathAndFileName = url,
DocumentTitle = $"Document {Path.GetFileName(url)}"
}, ct);
await _adamsClient.Package.FileIntoPackage(new FileIntoPackage.Request
{
DocumentAccessionNumber = docResponse.AccessionNumber,
PackageAccessionNumber = packageResponse.AccessionNumber
}, ct);
}
// 4. Your business logic: Update database
await _repository.SaveAccessionNumber(command.DocumentId, packageResponse.AccessionNumber);
return new UploadResult { AccessionNumber = packageResponse.AccessionNumber };
}
}
This is NOT duplication because it:
- Orchestrates multiple ADAMS API calls
- Integrates with your domain (database, business rules)
- Coordinates with other services (storage, notifications)
- Contains application-specific workflow logic
DO NOT create simple command wrappers that just forward to IAdamsApiClient - use Pattern 1 (direct API client) instead.
ADAMS Upload Workflow Pattern
Note: The ADAMS service currently uses Azure Blob Storage as the file storage location for document uploads. When uploading documents, you'll need to provide URLs to files stored in Azure Blob Storage.
The typical workflow for uploading documents to ADAMS involves multiple steps. Here's the recommended pattern:
1. Upload Files to Your Storage
// Upload file to your storage system (Azure Blob, AWS S3, file system, etc.)
var fileUrl = await _storageService.UploadFileAsync(fileStream, fileName);
2. Create ADAMS Folder
var folderResponse = await _adamsClient.Folder.AddNewFolderAsync(new AddNewFolderRequest
{
Title = "Project Documents",
FolderType = "ProjectFolder"
});
var folderId = folderResponse.FolderId;
3. Create Package (Optional)
var packageResponse = await _adamsClient.Package.AddNewPackageAsync(new AddNewPackageRequest
{
PackageTitle = "Document Package",
// ... other properties
});
var packageId = packageResponse.PackageId;
4. Add Documents to ADAMS
var documentResponse = await _adamsClient.Document.AddNewDraftAsync(new AddNewDraftRequest
{
Title = fileName,
DocumentType = "Report",
FileLocation = fileUrl, // URL from your storage system
// ... other properties
});
var accessionNumber = documentResponse.AccessionNumber;
5. File Documents into Folder/Package
// File into folder
await _adamsClient.Document.FileIntoFolderAsync(new FileIntoFolderRequest
{
AccessionNumber = accessionNumber,
FolderId = folderId
});
// Or file into package
await _adamsClient.Document.FileIntoPackageAsync(new FileIntoPackageRequest
{
AccessionNumber = accessionNumber,
PackageId = packageId
});
6. Store Accession Numbers
// Store the ADAMS accession number in your application database
await _repository.UpdateDocumentAsync(documentId, accessionNumber);
7. Submit to DPC (If Required)
await _adamsClient.Document.SubmitToDpcAsync(new SubmitToDpcRequest
{
AccessionNumber = accessionNumber
});
Authentication Strategies
Note: The ADAMS service currently uses Windows Authentication with Kerberos delegation. The ADAMS team is actively working on implementing OIDC authentication support, which will be available in a future release.
Windows Authentication with Kerberos Delegation
The WindowsAuthenticationStrategy uses WindowsIdentity.RunImpersonatedAsync to perform Kerberos delegation, allowing the ADAMS API calls to run under the authenticated user's context:
services.AddAdamsClient(configuration); // Default Windows Auth
Requirements:
- Windows Server environment
- Kerberos configured for delegation
- Application pool configured for Windows Authentication
Bearer Token Authentication
The BearerTokenAuthenticationStrategy supports OIDC/OAuth2 token-based authentication:
// Token from Authorization header
services.AddAdamsClientCore(configuration)
.AddBearerTokenAuthentication();
// Token from custom provider
services.AddAdamsClientCore(configuration)
.AddBearerTokenAuthentication(async () => await GetTokenAsync());
Token Resolution Order:
- Custom token provider (if configured)
Authorization: Bearer {token}headeraccess_tokenuser claim
No Authentication Strategy
For testing and development environments:
services.AddAdamsClientCore(configuration)
.AddNoAuthentication();
Running Tests
dotnet test
Contributing
- Follow Centeva coding standards (file-scoped namespaces, nullable reference types enabled)
- Maintain XML documentation comments for public APIs
- Add unit tests for new features
- Ensure all tests pass before submitting PRs
- Follow semantic versioning for releases
License
This project is licensed under the MIT License - see the LICENSE file for details.
Platform Compatibility
- Windows Authentication: Windows only (uses
WindowsIdentity.RunImpersonatedAsync) - Bearer Token Authentication: Cross-platform (Windows, Linux, macOS)
- No Authentication: Cross-platform
Dependency Notes
- Mediator: Uses Mediator.SourceGenerator (MIT license) instead of MediatR to avoid commercial licensing
- FluentValidation: Automatically integrated into Mediator pipeline when using
AddAdamsMediatorHandlers() - Entity Framework Core: Used for domain modeling, not for database access in this library
- ASP.NET Core MVC: Required only for SimulatedAdams test controllers
| 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 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. |
-
net10.0
- Ardalis.GuardClauses (>= 5.0.0)
- Centeva.DomainModeling.EFCore (>= 10.2.0)
- Centeva.RequestAuthorization (>= 2.1.0)
- Centeva.RequestBehaviors.Mediator (>= 1.0.0)
- FluentValidation (>= 12.1.1)
- Mediator.Abstractions (>= 3.0.2)
- Microsoft.AspNetCore.Components.Authorization (>= 8.0.11)
- Microsoft.AspNetCore.Mvc (>= 2.3.0)
- Microsoft.EntityFrameworkCore (>= 8.0.11)
- Microsoft.Extensions.Http (>= 8.0.1)
- VeracodeAttributes (>= 1.2.1)
-
net8.0
- Ardalis.GuardClauses (>= 5.0.0)
- Centeva.DomainModeling.EFCore (>= 10.2.0)
- Centeva.RequestAuthorization (>= 2.1.0)
- Centeva.RequestBehaviors.Mediator (>= 1.0.0)
- FluentValidation (>= 12.1.1)
- Mediator.Abstractions (>= 3.0.2)
- Microsoft.AspNetCore.Components.Authorization (>= 8.0.11)
- Microsoft.AspNetCore.Mvc (>= 2.3.0)
- Microsoft.EntityFrameworkCore (>= 8.0.11)
- Microsoft.Extensions.Http (>= 8.0.1)
- VeracodeAttributes (>= 1.2.1)
-
net9.0
- Ardalis.GuardClauses (>= 5.0.0)
- Centeva.DomainModeling.EFCore (>= 10.2.0)
- Centeva.RequestAuthorization (>= 2.1.0)
- Centeva.RequestBehaviors.Mediator (>= 1.0.0)
- FluentValidation (>= 12.1.1)
- Mediator.Abstractions (>= 3.0.2)
- Microsoft.AspNetCore.Components.Authorization (>= 8.0.11)
- Microsoft.AspNetCore.Mvc (>= 2.3.0)
- Microsoft.EntityFrameworkCore (>= 8.0.11)
- Microsoft.Extensions.Http (>= 8.0.1)
- VeracodeAttributes (>= 1.2.1)
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.0 | 47 | 5/28/2026 |