Usage
The HTML and JavaScript tabs build the identical FileUpload setup shown above, declaratively
via attributes or imperatively via the JS API. Unlike most other demos on this site,
fileupload is a dedicated ASP.NET Core middleware endpoint rather than a
Bindary-dispatched controller method, so it doesn't go through DataServer. The .NET Backend
tab shows that middleware.
<div id="fileUpload"
ui-type="FileUpload"
ui-drag-and-drop="true"
ui-accept="image/*"
ui-max-files="5"
ui-ajax='{"upload":{"url":"fileupload"}}'
ui-events='{ "onAjaxError": "$bindary.controller.fileUpload.ajaxError" }'>
</div>
fileupload is its own dedicated server endpoint, not a Bindary-dispatched
controller method, so no customParameters wiring is needed. The function
referenced above by name lives on this demo's Bindary controller:
$bindary.controller.fileUpload =
{
ajaxError: (fileUpload, args) =>
{
// FileUpload's own success handler reads the parsed JSON body from args.data,
// so the error path is expected to expose it the same way.
const message = args?.data?.message || 'Upload failed. Please try again.';
alert(message);
}
};
const fileUpload = $UI.createComponent(componyx.UI.FileUpload, {
id: 'fileUpload',
dragAndDrop: true,
containerElement: document.body
});
fileUpload.accept = 'image/*';
fileUpload.maxFiles = 5;
fileUpload.ajax.upload.url = 'fileupload';
fileUpload.events.onAjaxError.add(function (fileUpload, args)
{
const message = args?.data?.message || 'Upload failed. Please try again.';
alert(message);
});
fileUpload.show();
public class DemoFileUploadMiddleware
{
private const long MaxUploadSizeBytes = 8 * 1024 * 1024; // 8 MB
private readonly RequestDelegate _next;
private readonly ILogger<DemoFileUploadMiddleware> _logger;
public DemoFileUploadMiddleware(RequestDelegate next, ILogger<DemoFileUploadMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext httpContext)
{
var maxSizeFeature = httpContext.Features.Get<IHttpMaxRequestBodySizeFeature>();
if (maxSizeFeature != null && !maxSizeFeature.IsReadOnly)
maxSizeFeature.MaxRequestBodySize = MaxUploadSizeBytes;
try
{
var formOptions = new FormOptions
{
MultipartBodyLengthLimit = MaxUploadSizeBytes,
// keep it all in memory, never spill to a temp file
MemoryBufferThreshold = (int)MaxUploadSizeBytes
};
var form = await httpContext.Request.ReadFormAsync(formOptions);
if (form.Files.Count == 0)
{
await WriteResult(httpContext, StatusCodes.Status400BadRequest, false, "No file was received.");
return;
}
var fileNames = new List<string>();
foreach (var file in form.Files)
{
if (file.Length == 0)
continue;
if (file.Length > MaxUploadSizeBytes)
{
await WriteResult(httpContext, StatusCodes.Status413PayloadTooLarge, false,
"Beware of the maximum upload size of 8MB!");
return;
}
// Content is already fully received in memory at this point, nothing is
// written to disk, this demo only confirms the file arrived intact.
fileNames.Add(file.FileName);
}
await WriteResult(httpContext, StatusCodes.Status200OK, true, "Upload received.", fileNames);
}
catch (BadHttpRequestException ex)
{
_logger.LogWarning(ex, "Rejected oversized or malformed upload");
await WriteResult(httpContext, StatusCodes.Status413PayloadTooLarge, false,
"Beware of the maximum upload size of 8MB!");
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error handling demo upload");
await WriteResult(httpContext, StatusCodes.Status500InternalServerError, false,
"Upload failed. Please try again.");
}
}
private static async Task WriteResult(
HttpContext httpContext,
int statusCode,
bool success,
string message,
List<string> fileNames = null)
{
httpContext.Response.StatusCode = statusCode;
httpContext.Response.ContentType = "application/json";
await httpContext.Response.WriteAsJsonAsync(new
{
success,
message,
fileNames = fileNames ?? new List<string>()
});
}
}
Registered as its own branch in Startup.cs, separate from DataServer:
app.Map("/fileupload", b =>
{
b.UseMiddleware<DemoFileUploadMiddleware>();
});