The browser uploads each block via PutBlock against a pre-signed blob SAS URL, then finalises with a single PutBlockList. Mirrors the S3 pattern — your server signs once and the bytes bypass IIS entirely. IndexedDB resume preserves the upload session + already-committed block IDs so reloads pick up where they stopped.
Setup required. No
IAzureSigner is registered yet, so
/ajaxupload.axd/azure/* currently returns 501. To activate this demo:
- Install
Azure.Storage.Blobs into bin/ (from NuGet).
- Move
v5-signers/DemoAzureSigner.cs.template → App_Code/DemoAzureSigner.cs.
- Fill in
DemoAzure:* values in web.config.
- Recycle the app pool.
Full walk-through:
v5-signers/README.md.
Client config
AjaxUploader.create('#uploader', {
uploadUrl: '/ajaxupload.axd/upload',
strategy: 'azure',
chunkSize: 4 * 1024 * 1024, // Azure block size
chunkConcurrency: 4,
persistState: true,
persistAdapter: 'indexeddb'
});
Server-side (Global.asax.cs)
using AjaxUploader.Providers;
protected void Application_Start(object sender, EventArgs e)
{
// Your IAzureSigner wraps BlobServiceClient and hands out SAS URLs.
Azure.Signer = new MyAzureSigner(
connectionString: ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString,
containerName: "uploads");
}
Wire protocol
POST /ajaxupload.axd/azure/create → { uploadId, blobUrl, blockIdPrefix }
PUT {blobUrl}&comp=block&blockid=... per block (browser-direct)
PUT {blobUrl}&comp=blocklist with XML BlockList body (browser-direct)
POST /ajaxupload.axd/azure/complete to record metadata server-side
Container CORS
az storage cors add \
--methods PUT \
--origins https://ajaxuploader.com \
--allowed-headers "*" \
--exposed-headers "*" \
--services b \
--max-age 3600