Kanject.FileServer

View .md

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

csharp
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 DI​var 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).

csharp
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}Async methods and pre-signed upload URLs, no boilerplate.
  • Content validation — a shipped IFileContentValidator rejects 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 partial class — location, accepted types, and limits as attributes.
  • Upload + signed URLs are source-generated; override a method only to add a hook.
  • MaximumFileSize is in KB — 4000 for ~4 MB.
Was this page helpful?