I can now list my files in the upload control. Now, how do I get the stream from the collection of files? I need to have the stream in order to upload to Azure.
foreach (UploadFileInfo file in args.Files) { var fileName = Path.GetFileName(file.Name); //await using (var fileStream = new FileStream(fileName, FileMode.Create))
Is there a way to filter which file extensions are allowed to be selected? I limit to PDF or PNG but it allows me to select XML.
<div>
<hr />
<h4 class="gsi-padding-tb0-lr12">Upload File to Session...</h4>
<TelerikUpload AllowedExtensions="@( new List<string>() { ".pdf", ".png" } )"
OnSelect="@OnUploadSelect"
OnCancel="@OnUploadCancel"
OnRemove="@OnUploadRemove">
</TelerikUpload>
<div class="demo-hint gsi-padding-tb0-lr12">
<small>
Upload <strong>PDF</strong> or <strong>PNG</strong> files with a maximum size of <strong>6MB</strong>.
</small>
</div>
</div>
I have a blazor hybrid app with a basic FileSelect component. When I start the Windows Native MAUI app, the drag-and-drop feature of the component does not work at all. The drag of any file into the MAUI window shows a stop/not possible sign as the mouse pointer. In the Web version everything works as expected.
There was also no note here that this might not work due to some restriction
I have a Blazor server solution with separate projects for the UI and API. When the Upload component is configured to use a controller in the API project to handle the save function I get the error seen in the attached file 'Screenshot 2025-02-26 132709' but the file is successfully uploaded. If I copy the same controller to the UI project the error goes away see 'Screenshot 2025-02-26 132538'.
to get the save function to work with the API at all I had to add the below HTTP options section to the API program.cs
app.Use(async (context, next) => { if (context.Request.Method == HttpMethods.Options) { context.Response.Headers.Add("Allow", "GET, POST, PUT, OPTIONS"); context.Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:7053"); context.Response.StatusCode = (int)HttpStatusCode.OK; return; } await next.Invoke(); });
Upload component:
<TelerikUpload SaveUrl="@saveURL"
RemoveUrl="https://localhost:7121/api/DocumentUpload/remove"
MaxFileSize="@MaxFileSize"
/>
Controller:
using DocumentFormat.OpenXml.Drawing;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class DocumentUploadController : ControllerBase
{
public IWebHostEnvironment HostingEnvironment { get; set; }
public DocumentUploadController(IWebHostEnvironment hostingEnvironment)
{
HostingEnvironment = hostingEnvironment;
}
[HttpPost("save")]
public async Task<IActionResult> Save(IFormFile files) // "files" matches the Upload SaveField value
{
if (files != null)
{
try
{
// save to wwwroot - Blazor Server only
//var rootPath = HostingEnvironment.WebRootPath;
// save to Server project root - Blazor Server or WebAssembly
var rootPath = HostingEnvironment.ContentRootPath;
var newFolder = Guid.NewGuid().ToString();
System.IO.Directory.CreateDirectory(rootPath + newFolder);
var saveLocation = System.IO.Path.Combine(rootPath + newFolder, files.FileName);
using (var fileStream = new FileStream(saveLocation, FileMode.Create))
{
await files.CopyToAsync(fileStream);
}
}
catch (Exception ex)
{
Response.StatusCode = 500;
await Response.WriteAsync($"Upload failed.");
}
}
return new OkResult();
}
[HttpPost("remove")]
public async Task<IActionResult> Remove([FromForm] string files) // "files" matches the Upload RemoveField value
{
if (files != null)
{
try
{
// delete from wwwroot - Blazor Server only
var rootPath = HostingEnvironment.WebRootPath;
// delete from Server project root - Blazor Server or WebAssembly
//var rootPath = HostingEnvironment.ContentRootPath;
var fileLocation = System.IO.Path.Combine(rootPath, files);
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
}
catch (Exception ex)
{
Response.StatusCode = 500;
await Response.WriteAsync($"Delete failed.");
}
}
return new EmptyResult();
}
}
}
Any ideas? Have I missed something I need to setup in the API program.cs?
@page "/SDS"
@using SafetySite.Models;
@using Helpers
@inject SDSModel SDSModel
@inject UserModel UserModel
@inject NavigationManager NavigationManager
<PageTitle>Safety Data Sheets</PageTitle>
<TelerikGrid Data=@SDSItemsList
FilterMode="GridFilterMode.FilterMenu"
Sortable="true"
EditMode="GridEditMode.Inline"
Height="2000px">
<GridToolBarTemplate>
<GridCommandButton Command="Add" Icon="@SvgIcon.Plus" Enabled="@UserModel.CanEdit()">Add SDS Sheet</GridCommandButton>
</GridToolBarTemplate>
<GridColumns>
<GridColumn Field="@(nameof(SDSModel.FileExists))" Title="File" Width="120px">
<EditorTemplate>
@{
var item = context as SDSModel;
if(item != null)
{
<TelerikButton OnClick="@(() => ToggleUploadWindow(item))"
Icon="@SvgIcon.Upload"
Class="btn btn-sm btn-primary">
Upload File
</TelerikButton>
}
}
</EditorTemplate>
<Template>
@{
var item = context as SDSModel;
if(item != null)
{
<div class="text-center">
<TelerikButton OnClick="@(() => NavigateToViewSDSFile(item.FileName!))"
Class="navlinkgrow">
<div class="navlink-content">
<span class="@(item.FileExists ? "text-success" : "text-danger")">
<i class="fa-duotone fa-solid fa-file-pdf fa-2x"></i>
</span>
</div>
</TelerikButton>
</div>
}
}
</Template>
</GridColumn>
<GridColumn Field="@nameof(SDSModel.Title)"
Title="Title"
Editable="true" />
<GridColumn Field="@nameof(SDSModel.Revision)"
Title="Revision"
Editable="true" />
<GridColumn Field="@nameof(SDSModel.CurrentVersion)"
Title="CurrentVersion"
Editable="true">
<Template>
@{
var item = context as SDSModel;
if (item != null)
{
<input type="checkbox" checked="@item.CurrentVersion" disabled />
}
}
</Template>
</GridColumn>
<GridColumn Field="@nameof(SDSModel.CreatedBy)"
Title="Created By"
Editable="false" />
<GridColumn Field="@nameof(SDSModel.EditedBy)"
Title="Edited By"
Editable="false" />
<GridColumn Field="@nameof(SDSModel.CreationDate)"
Title="Creation Date"
DisplayFormat="{0:yyyy-MM-dd}"
Editable="false" />
<GridColumn Field="@nameof(SDSModel.EditedDate)"
Title="Edit Date"
DisplayFormat="{0:yyyy-MM-dd}"
Editable="false" />
<GridCommandColumn>
<GridCommandButton Command="Save"
Icon="@SvgIcon.Save"
ShowInEdit="true"
Enabled="@UserModel.CanEdit()"
OnClick="@OnUpdate">
Update
</GridCommandButton>
<GridCommandButton Command="Edit"
Icon="@SvgIcon.Pencil"
Enabled="@UserModel.CanEdit()">
Edit
</GridCommandButton>
<GridCommandButton Command="Delete"
Icon="@SvgIcon.Trash"
Enabled="@UserModel.CanEdit()"
OnClick="@OnDelete">
Delete
</GridCommandButton>
<GridCommandButton Command="Cancel"
Icon="@SvgIcon.Cancel"
ShowInEdit="true"
Enabled="@UserModel.CanEdit()">
Cancel
</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@* THIS TELERIK WINDOW OPENS A POPUP OF A TELERIK FILE MANAGER THAT ALLOWS FOR THE INDIVIDUAL TO PLACE A PDF ASSOCIATED WITH THAT ITEM INTO THE FOLDER *@
<TelerikWindow Width="400px" Height="fit-content" Centered="true" @bind-Visible="@IsUploadFileWindowVisible">
<WindowTitle>
<strong>Upload SDS File</strong>
</WindowTitle>
<WindowActions>
<WindowAction Name="Close" OnClick="@(() => IsUploadFileWindowVisible = !IsUploadFileWindowVisible)" />
</WindowActions>
<WindowContent>
<TelerikUpload Multiple="false"
SaveUrl="@SaveUrl"
RemoveUrl="@RemoveUrl"
OnSuccess="@OnFileUploadSuccess"
AllowedExtensions="@AllowedExtensions"
MaxFileSize="10485760"/>
</WindowContent>
</TelerikWindow>
@code {
private bool IsUploadFileWindowVisible { get; set; } = false;
private List<SDSModel> SDSItemsList = new();
private SDSModel? CurrentItem { get; set; } = new SDSModel();
private List<string> AllowedExtensions = new List<string> { ".pdf" };
private bool CanSaveUpload { get; set; } = false;
private string SaveUrl = String.Empty;
private string RemoveUrl = String.Empty;
public void ToggleUploadWindow(SDSModel item)
{
CurrentItem = item;
SaveUrl = $"{NavigationManager.BaseUri}api/Upload/SavePdf?rev={item.Revision}";
RemoveUrl = $"{NavigationManager.BaseUri}api/Upload/RemovePdf";
IsUploadFileWindowVisible = !IsUploadFileWindowVisible;
}
private void NavigateToViewSDSFile(string fileName)
{
if (!string.IsNullOrEmpty(fileName))
{
string fileUrl = $"/SafetyDataSheets/{fileName}";
NavigationManager.NavigateTo(fileUrl, forceLoad: true);
}
else
{
Console.WriteLine("No document found for the specified file name.");
}
}
private async Task OnFileUploadSuccess(UploadSuccessEventArgs args)
{
if (CurrentItem != null && args.Files.Count > 0)
{
var uploadedFile = args.Files[0];
string fileName = uploadedFile.Name;
// Check if a file with the same name already exists in the database
bool fileExists = await SDSModel.FileExistsAsync(fileName);
if (fileExists)
{
var existingItem = await SDSModel.GetSDSItemByFileNameAsync(fileName);
if(existingItem != null)
{
existingItem.CurrentVersion = false;
await SDSModel.UpdateOldSDSItemAsync(existingItem.FileName, UserModel.EmployeeID);
CurrentItem.Revision = existingItem.Revision + 1;
fileName = $"{Path.GetFileNameWithoutExtension(uploadedFile.Name)}_rev{CurrentItem.Revision}{Path.GetExtension(uploadedFile.Name)}";
}
}
CurrentItem.FileName = fileName;
CurrentItem.FileExists = true;
CurrentItem.CurrentVersion = true;
}
}
private async Task OnUpdate(GridCommandEventArgs args)
{
var item = args.Item as SDSModel;
if (item != null)
{
item.EditedBy = UserModel.EmployeeID;
await SDSModel.SaveSDSItemAsync(item);
SDSItemsList = await SDSModel.GetSDSItemsAsync();
}
}
private async Task OnDelete(GridCommandEventArgs args)
{
var item = args.Item as SDSModel;
if (item != null)
{
await SDSModel.DeleteSDSItemAsync(item);
SDSItemsList = await SDSModel.GetSDSItemsAsync();
}
}
protected override async Task OnInitializedAsync()
{
SDSItemsList = await SDSModel.GetSDSItemsAsync();
await base.OnInitializedAsync();
}
}
Hi,
Hi I am writing an app where user can upload files (multiple at once) and each file will have custom data attached to it.
How do I access individual files and attach custom data to each file once I load them into the select file grid?
Almost like a SelectedItem event in a grid where I can access the individual files which I click on it.
I can use the OnUpload and OnSelect to send custom data and look through all the files but They aren't bind to the individual file.
Example, I have data like a description for each individual files that I want to send with it when I upload and write to the database. How do I bind that data to the file?
I am working on a Blazor Auto application using the Upload component to upload images for a product for various properties in a SaaS type system.
I found that when I adjust the save point in the application at runtime the SaveUrl does not seem to retain the value.
For example:
SaveImageUrl = $"api/property/{TenantSelectionService.SelectedTenant.Id}/product-types/{TypeCode}/images";
<TelerikUpload AllowedExtensions="@(new List<string>() {".jpg", ".jpeg", ".webp" })"
SaveUrl="@SaveImageUrl"
WithCredentials="true"
OnUpload="@OnUploadAsync">
This is set in two locations, OnAfterRender as well as OnTenantSelectionChanged event.
When using this method, it appears that the Upload component does not retain the SaveUrl for some reason. When examining the JavaScript, the URL is always blank.
I did manage to alter the URL to a static version and pass data as a header.
Is this something that can be looked into or maybe I am doing it wrong.
hi.
I just now updated through NuGet to 6.0.2 and started seeing this message on the TelerikUpload component.
How should I resolve this? I am uploading large files
Thanks
Unable to set property 'MaxFileSize'
In the documentation (link) is written that "Configure the integrated Upload through the FileManagerUploadSettings child tag of FileManagerSettings. The FileManager exposes parameter names that are identical to the respective Upload component API members", but the FileManagerUploadSettings expose only a subset of upload properties.
This is a very limitation because we can't customize the upload or support the upload of multiple file.
I think the documentation needs to be correct, or what I would prefer, that all the properties be correctly exposed by FileManagerUploadSettings.
thanks
--
Andrea