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
  • Provision FileServer into your AWS 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

bash
kanject baas deploy fileserver --env dev

Register it in your service

csharp
using Kanject.FileServer.Provider.AwsV2.Extensions;var builder = WebApplication.CreateBuilder(args);// Register with a typed options delegate. DbConfig carries the AWS region// and per-stage namespace; lifecycle expiration is opt-in.builder.Services.AddAwsFileServer(options =>{    options.DbConfig.AwsRegion = appSettings.AwsRegion;    options.DbConfig.Namespace = appSettings.Stage;});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 scopingStorageLocation.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
  • Provision with kanject baas deploy fileserver, register with AddAwsFileServer(options => …).
  • 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?