Skip to main content

Get Linked File Meta Handler

This page provides complete examples for implementing the Get Linked File Meta backend handler. The getlinkedfilemetaevent endpoint retrieves file metadata (name, size, MIME type) without downloading the actual file content.

What is Get Linked File Meta?

getlinkedfilemetaevent is the backend endpoint that:

  • Receives a file identifier
  • Retrieves file metadata from storage
  • Returns file name, size, and MIME type
  • Does NOT download the file content (fast and lightweight)

Complete Get Linked File Meta Implementation

Choose your backend language:

Controllers/FormsPublicController.cs
public class LinkedFileRequestDto
{
public string FileId { get; set; }
}

[HttpPost("getlinkedfilemetaevent")]
[AllowAnonymous]
public async Task<IActionResult> GetLinkedFileMeta([FromBody] LinkedFileRequestDto request)
{
string tenantId = GetCurrentTenantId();

string fileName = string.Empty;
long fileSize = 0;
string fileMimetype = "application/octet-stream";

var fileStorageService = GetFileStorageService();
if (fileStorageService == null)
throw new InvalidOperationException("File storage provider not configured.");

if (!string.IsNullOrEmpty(request.FileId))
{
// Parse file identifier (format: "bucket-name:path/to/file.pdf")
string[] parts = request.FileId.Split(':');
string bucketName = parts[0];
string filePath = parts[1];

// Extract filename from path
fileName = Path.GetFileName(filePath);

// Get metadata from storage (lightweight operation)
var metadata = await fileStorageService.GetFileMetadataAsync(
tenantId,
filePath,
bucketName
);

fileSize = metadata?.ContentLength ?? 0;
fileMimetype = GetMimeType(filePath);
}

// Build response
var response = new HandlerResponse();
response.Set(HandlerResponse.LinkedFileName, fileName);
response.Set(HandlerResponse.LinkedFileSize, fileSize);
response.Set(HandlerResponse.LinkedFileMimetype, fileMimetype);

return Ok(await response.Get());
}

private string GetMimeType(string fileName)
{
var extension = Path.GetExtension(fileName).ToLowerInvariant();

return extension switch
{
".pdf" => "application/pdf",
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".doc" => "application/msword",
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls" => "application/vnd.ms-excel",
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".zip" => "application/zip",
".txt" => "text/plain",
".mp4" => "video/mp4",
".mp3" => "audio/mpeg",
_ => "application/octet-stream"
};
}

Request Structure

{
"fileId": "bucket-name:tenant/forms/2026/01/27/document.pdf"
}

Key Fields:

  • fileId - The file identifier returned from the upload endpoint

Response Structure

{
"linkedFileName": "document.pdf",
"linkedFileSize": 1048576,
"linkedFileMimetype": "application/pdf"
}

Response Fields:

  • linkedFileName - The file name without path
  • linkedFileSize - File size in bytes
  • linkedFileMimetype - The MIME type of the file

Storage Implementation Examples

S3 Storage Metadata

C# - Get File Metadata from S3
public async Task<GetObjectMetadataResponse> GetFileMetadataFromS3(
string tenantId,
string filePath,
string bucketName)
{
var s3Client = new AmazonS3Client(/* credentials */);

var metadataRequest = new GetObjectMetadataRequest
{
BucketName = bucketName,
Key = filePath
};

return await s3Client.GetObjectMetadataAsync(metadataRequest);
}

Local File Storage Metadata

C# - Get File Metadata from Local Storage
public Task<FileMetadata> GetFileMetadataFromLocal(
string tenantId,
string filePath,
string bucketName)
{
var fullPath = Path.Combine(_uploadDirectory, bucketName, filePath);

if (!File.Exists(fullPath))
throw new FileNotFoundException("File not found", fullPath);

var fileInfo = new FileInfo(fullPath);

return Task.FromResult(new FileMetadata
{
ContentLength = fileInfo.Length,
LastModified = fileInfo.LastWriteTimeUtc,
ETag = ComputeETag(fullPath)
});
}

Azure Blob Storage Metadata

C# - Get File Metadata from Azure Blob
public async Task<BlobProperties> GetFileMetadataFromAzure(
string tenantId,
string filePath,
string containerName)
{
var blobClient = new BlobContainerClient(
_connectionString,
containerName
);

var blob = blobClient.GetBlobClient(filePath);

if (!await blob.ExistsAsync())
throw new FileNotFoundException("Blob not found", filePath);

var properties = await blob.GetPropertiesAsync();

return properties.Value;
}

Use Cases

Display File Information

Show file details without downloading:

TypeScript - Display File Information
async function displayFileInfo(fileId: string) {
const response = await fetch('/your-api-path/getlinkedfilemetaevent', {
method: 'POST',
body: JSON.stringify({ fileId }),
headers: { 'Content-Type': 'application/json' }
});

const meta = await response.json();

console.log(`File: ${meta.linkedFileName}`);
console.log(`Size: ${formatBytes(meta.linkedFileSize)}`);
console.log(`Type: ${meta.linkedFileMimetype}`);
}

function formatBytes(bytes: number): string {
if (bytes === 0) return '0 Bytes';

const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));

return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
}

Validate File Size Before Download

Check if file is too large before attempting download:

TypeScript - Validate File Size Before Download
async function downloadIfNotTooLarge(fileId: string, maxSizeMB: number) {
const meta = await getFileMeta(fileId);
const maxBytes = maxSizeMB * 1024 * 1024;

if (meta.linkedFileSize > maxBytes) {
alert(`File is too large (${formatBytes(meta.linkedFileSize)}). Maximum is ${maxSizeMB}MB.`);
return;
}

// Proceed with download
await downloadFile(fileId);
}

Show File Icons

Display appropriate icons based on file type:

TypeScript - Get File Icon by MIME Type
function getFileIcon(mimeType: string): string {
const iconMap: Record<string, string> = {
'application/pdf': 'pdf-icon.svg',
'image/jpeg': 'image-icon.svg',
'image/png': 'image-icon.svg',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'word-icon.svg',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'excel-icon.svg'
};

return iconMap[mimeType] || 'file-icon.svg';
}

Performance Benefits

Lightweight Operation

Getting metadata is much faster than downloading the file:

Full File Download: ~500ms for 10MB file
Metadata Only: ~50ms for same file

Cache Metadata

Cache file metadata to avoid repeated requests:

C# - Cache File Metadata
private readonly IMemoryCache _cache;

public async Task<FileMetadata> GetFileMetadataWithCache(string fileId)
{
var cacheKey = $"file-meta:{fileId}";

if (_cache.TryGetValue(cacheKey, out FileMetadata cached))
{
return cached;
}

var metadata = await GetFileMetadataFromStorage(fileId);

_cache.Set(cacheKey, metadata, TimeSpan.FromMinutes(15));

return metadata;
}

Error Handling

C# - Handle Errors
public async Task<IActionResult> GetLinkedFileMeta([FromBody] LinkedFileRequestDto request)
{
try
{
if (string.IsNullOrEmpty(request.FileId))
{
return BadRequest(new {
error = "File ID is required"
});
}

// Check authorization
if (!await CanUserAccessFile(GetCurrentUserId(), request.FileId))
{
return Unauthorized(new {
error = "Access denied"
});
}

// Get metadata
var metadata = await GetFileMetadata(request.FileId);

if (metadata == null)
{
return NotFound(new {
error = "File not found"
});
}

return Ok(new {
linkedFileName = metadata.FileName,
linkedFileSize = metadata.Size,
linkedFileMimetype = metadata.MimeType
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving file metadata");
return StatusCode(500, new {
error = "Failed to retrieve file metadata"
});
}
}

Next Steps