Upgrading to 5.0
This guide covers upgrading an app from 4.x to 5.0. Most of the changes are in chunked uploads: apps register their upload store, and stores of an app's own implement a few new members.
Before Upgrading
- Upgrade servers that share an upload directory or store together: 4.x and 5.0 servers can't share one.
- Uploads that 4.x finished are removed when the 5.0 app starts, so a completion made again for one of them fails with
404(upload-not-found). Uploads that are still receiving chunks carry on. - 4.x clients keep working against a 5.0 service. A 5.0 client of a 4.x service uploads small files with the three requests after the service answers its direct upload with
405.
Registration and Options
AddChunkedUploadsno longer registers an upload store, andChunkedUploadOptions.Directoryis gone. Register the directory store with AddDirectoryUploadStore, setting its required Directory and SharingMode, or register a store of your own; without one, the app fails to start (see The directory store).- With ProcessLocal, the directory store locks its directory, so a second process that starts while the first runs, such as with IIS overlapped recycling, fails to start. With Shared, the short-lived store must be shared too.
- Paths are absolute paths of Singulink.IO.FileSystem:
- Directory is an
IAbsoluteDirectoryPath. CloudflareForwardingOptions.SavedRangesPathis replaced by SavedRangesFile, anIAbsoluteFilePath.UploadedFile.FilePathis replaced by File, and MoveToAsync and the matching members of UploadContent take anIAbsoluteFilePath.- SessionTokenStore.FolderPath is an
IAbsoluteDirectoryPath. - Relative paths are no longer resolved against the content root, and a path with names that are not friendly, such as one that ends with a space or a dot, throws an ArgumentException.
- Directory is an
- RelyingPartyId, RelyingPartyName, SavedRangesFile and PermitLimit are
required: options created in code set them, and options bound from configuration without them fail at startup. PasskeyOptions.RequireUserVerificationandRequireDiscoverableCredentialsare replaced by UserVerification and DiscoverableCredentials:truebecomesRequired(the default) andfalsebecomesPreferred.- Options can't be changed once the library has taken them, and an invalid value throws when it is set rather than when the app starts.
- IdleExpiry no longer limits how long a handler runs; ProcessingTimeout does, 1 hour by default. An app that set
IdleExpiryto stop handlers sooner setsProcessingTimeoutinstead. IdleExpiryis 15 minutes by default rather than 1 day, so a client that is away longer between requests finds its upload gone.- The limits of open uploads are counted in the short-lived store, which servers that share uploads must share too (see Limits of open uploads).
AddShortLivedStore(options => ...)no longer sets the memory store's size: the named options of each key of ShortLivedStoreKeys do.
Cancelling Uploads
- A cancellation no longer deletes an upload whose handler is running: it cancels the handler's token, and a handler that finishes anyway has its outcome stored. Handlers stop or finish once their token is cancelled (see Cancelling an upload).
- An upload of the toolkit's client that is cancelled after its handler may have started waits for the service, and returns the handler's result if it finished (see Cancellation and Aborting).
Direct Uploads and Upload IDs
- A file that fits in one chunk is uploaded in one request,
POST {pattern}/uploads/direct, with the file as its body (see Direct Uploads). Proxy, firewall and gateway rules, rate limits of the endpoint group, and middleware, filters, validators or handlers that read the request see it. - An app with a CORS policy of its own allows the
Upload-Creationrequest header for its upload endpoints and exposesLocation. - An override of
SendStreamingAsyncor anHttpHandlerthat matches upload paths also sees direct uploads, and tests with a fake service or FaultInjectionHandler see them first for small files. - Clients choose the IDs of their uploads, GUIDs (CreateUploadCommand.Id), in place of idempotency keys (see Upload IDs). A validator can run more than once for one upload.
- New error codes:
upload-direct-too-large,upload-creation-header-too-large,upload-cancelled,upload-finished,upload-id-conflictandupload-cancellation-unavailable. An exception handler that words errors by their codes covers them too (see Messages of the service's errors).
Stores of Your Own
An IUploadStore of the app's own keeps finished uploads apart from the open ones (see Stores of your own):
- New members without a default implementation: SharingMode, GetUsageAsync and RemoveOutcomesAsync.
- Uploads are kept by their user and ID. TryCreateAsync returns an UploadCreationResult, and creates an upload unless the user has one with its ID.
- The idempotency key members are gone:
ReserveKeyAsync,ReleaseKeyAsync,IsKeyReservedAsync,UploadKeyReservationandUploadRecord.IdempotencyKey. - ListAsync lists only open uploads, and has no
userIdorwithoutOutcomesparameter. - TrySetOutcomeAsync, GetAsync, DeleteAsync and WriteChunkAsync have new guarantees, which UploadStoreContract.CheckAsync and the new UploadStoreContract.CheckOutcomeRemovalAsync check. The latter removes outcomes of all users, so it runs only against a store that holds test data.
An IShortLivedStore of the app's own implements the new SharingMode, SetAsync and GetUsageAsync (see The operations).
Next Steps
Continue with these related articles:
- Chunked Uploads - Upload endpoints, their limits and their storage.
- Chunked Uploads in Client Apps - Sending files from client apps.
- Upload Format - The requests and responses of the protocol.