Kanject.FileServer
Secure, scalable file storage — declarative resource servers, source-generated upload methods and signed upload URLs, S3-backed, deployed into your own AWS.
You'll learn
- Know which AWS resources FileServer creates in your account
- Register it with
AddAwsFileServer - Declare a resource server — location, accepted types, size and count limits
- Get source-generated upload methods + signed upload URLs, overriding only for hooks
Provision
FileServer creates its S3 bucket — private, bucket-owner-enforced — if there isn't one by the configured name, and its DynamoDB tables when DbConfig.CreateTableCheck is true. Point it at a bucket you already own and it uses that instead.
Register it in your service
using Kanject.FileServer.Provider.AwsV2.Extensions;var builder = WebApplication.CreateBuilder(args);// Register with a typed options delegate. DbConfig is FileServer's DynamoDB// table (region + per-stage namespace); Region and BucketName are the S3// bucket. Lifecycle expiration is opt-in.builder.Services .AddAwsFileServer(options => { options.DbConfig.AwsRegion = appSettings.AwsRegion; options.DbConfig.Namespace = appSettings.Stage; options.Region = appSettings.AwsRegion; options.BucketName = appSettings.FileBucketName; // Generated from your [ResourceServer] classes (below), in your // assembly's namespace. Registration throws if none are defined. options.ResourceTypeDefinitions.AddResourceTypeDefinitions(); }) .AddResourceServers(); // also generated: registers each server in DIvar app = builder.Build();app.Run(); Declare a resource server
A resource server is a partial class described by attributes: where it stores (Public/Private), what it accepts, and its limits. Upload and signed-URL methods are source-generated — override one only when you need a hook (hashing, transcoding, custom metadata).
using Kanject.FileServer.Abstractions.Attributes;using Kanject.FileServer.Abstractions.Enums;// Each resource = a declarative server. Public bucket, image-only,// max 4 MB × 10 files; upload + signed URLs are source-generated.[FileServer(Version = 2)][ResourceServer(Location = StorageLocation.Public, Path = "item-images")][AcceptedFileTypes(".jpeg", ".jpg", ".png", ".webp")][FileUploadSettings(MaximumFileSize = 4000, MaximumFileCount = 10)]public partial class ItemResourceServer{ // Override the generated method only when you need a hook — here: // hash the bytes and transcode to WebP before storage. public override async Task<ResourceMetadata?> UploadItemAsync( IFormFile file, string resourceId, Guid ownerId, Dictionary<string, string>? metadata = null) { metadata ??= new(); metadata["contentHash"] = Sha256(file.OpenReadStream()); return await base.UploadItemAsync( await file.ConvertToWebPFile(), resourceId, ownerId, metadata); }}// Private bucket, PDF-only, 200 KB cap. Zero override required.[FileServer(Version = 2)][ResourceServer(Location = StorageLocation.Private, Path = "shipping-labels")][AcceptedFileTypes(".pdf")][FileUploadSettings(MaximumFileSize = 200)]public partial class ShippingLabelResourceServer; What you get
- Declarative resource servers — storage location, accepted types, and size/count limits as attributes.
- Source-generated upload — typed
Upload{Resource}Asyncmethods and pre-signed upload URLs, no boilerplate. - Content validation — a shipped
IFileContentValidatorrejects dangerous PDFs (JavaScript / launch actions) and strips JPEG EXIF; plug in your own for more. - Public / private + owner scoping —
StorageLocation.Public/Private, with owner-id validation on read and delete. - Accepted-type + size enforcement —
[AcceptedFileTypes]and[FileUploadSettings]gate every upload. - Lifecycle expiration — opt-in object expiry and incomplete-multipart cleanup.
Recap
- Register with
AddAwsFileServer(options => …); it creates its S3 bucket if it's missing. - A resource server is a declarative
partialclass — location, accepted types, and limits as attributes. - Upload + signed URLs are source-generated; override a method only to add a hook.
MaximumFileSizeis in KB —4000for ~4 MB.
Related modules
Forms
Form-attachment storage backend.
Identity
Pair with auth for owner-scoped access.
EventHub
Trigger pipelines on upload.
Was this page helpful?