@ -33,7 +33,7 @@ If you modified your solution structure, adding module using ABP CLI might not w
In order to do that, add packages listed below to matching project on your solution. For example, `Volo.FileManagement.Application` package to your **{ProjectName}.Application.csproj** like below;
@ -46,7 +46,7 @@ After adding the package reference, open the module class of the project (eg: `{
)]
```
> If you are using Blazor Web App, you need to add the `Volo.FileManagement.Blazor.WebAssembly` package to the **{ProjectName}.Blazor.Client.csproj** project and ad the `Volo.Chat.FileManagement.Blazor.Server` package to the **{ProjectName}.Blazor.csproj** project.
> If you are using Blazor Web App, add the `Volo.FileManagement.Blazor.WebAssembly` package to the **{ProjectName}.Blazor.Client.csproj** project and the `Volo.FileManagement.Blazor.Server` package to the **{ProjectName}.Blazor.csproj** project.
If your project is using `EntityFrameworkCore`, you need to add following configuration to `OnModelCreating` method at your `DbContext`.
File Management module's MVC user interface depends on following npm packages. add `@volo/file-management` npm package to your `package.json` file.
```json
"dependencies": {
...
"@volo/file-management": "^2.9.0"
{
"dependencies": {
"@volo/file-management": "~x.x.x"
}
}
```
> After adding packages, you need to run `abp install-libs` command in the folder of your `Web` project.
#### Angular UI
For user interface, an Angular module called `FileManagementModule` is included in the `@volo/abp.ng.file-management` library.
For a standalone Angular application, register the File Management menu configuration in `app.config.ts`:
Please visit [document on feature libraries](../framework/ui/angular/feature-libraries.md) to learn how you can install and set it up in your Angular application.
```ts
import { ApplicationConfig } from '@angular/core';
import { provideFileManagementConfig } from '@volo/abp.ng.file-management/config';
#### Blazor & Blazor Server
export const appConfig: ApplicationConfig = {
providers: [provideFileManagementConfig()],
};
```
[There is a known problem with ASP NET Core](https://github.com/dotnet/aspnetcore/issues/38842#issuecomment-1342540950), You have to set `DisableImplicitFromServicesParameters` of `HubOptions` to `true`.
Lazy-load the File Management routes in `app.routes.ts`:
The `createRoutes` function accepts `entityActionContributors`, `toolbarActionContributors`, `entityPropContributors` and `xsrfHeaderName`. These contributors target `eFileManagementComponents.FolderContent`. See the Angular guides for [entity actions](../framework/ui/angular/entity-action-extensions.md), [page toolbars](../framework/ui/angular/page-toolbar-extensions.md) and [table columns](../framework/ui/angular/data-table-column-extensions.md).
Use `withUppyOptions` with `provideFileManagementConfig` when you need to customize the Angular uploader's Uppy options. The startup templates already register the provider and lazy route when the module is selected.
Please visit [document on feature libraries](../framework/ui/angular/feature-libraries.md) to learn how you can install and set it up in your Angular application.
## Setting BLOB Provider
File Management module is based on the [BLOB Storing](../framework/infrastructure/blob-storing) system as defined before, and it uses `FileManagementContainer` as a BLOB container.
Please check the [BLOB Storage Providers documentation](../framework/infrastructure/blob-storing#blob-storage-providers) for more information about providers and how to use them.
File contents are stored with the file descriptor's ID as the BLOB name. Renaming or moving a file only changes its descriptor. Deleting a file removes both the descriptor and its BLOB. Deleting a directory recursively deletes its subdirectories, file descriptors and file BLOBs, so treat directory deletion as a destructive operation.
The descriptor database and the configured BLOB provider are separate resources. A custom workflow that calls the domain services directly should handle failures between metadata and BLOB operations; a database transaction cannot roll back an external BLOB provider.
## Packages
This module follows the [module development best practices guide](../framework/architecture/best-practices) and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them.
@ -144,12 +165,52 @@ You can move files by clicking `Actions -> Move` on the table.
You can rename a file by clicking `Actions -> Rename` on the table.
The **Download** action first requests a short-lived download token and then navigates to the download endpoint. The **Preview** action is available for supported image files. The **Delete** action removes the stored content in addition to its file descriptor.
The built-in UIs require an explicit overwrite choice when a file with the same name already exists in the current directory. Their upload pre-checks validate names, detect duplicates and check the current storage quota before the file content is sent. The upload HTTP API does not require this pre-check, and `CreateFileInputWithStream.OverrideExisting` defaults to `true`. A direct API client should call the pre-check endpoint and set `OverrideExisting` explicitly when it needs the same protection.
###### File Sharing
To share a file, click `Actions -> Share` in the table. Once sharing is enabled, you can copy the shared link directly from the table.
> Anyone with the shared link will be able to access the file while sharing is enabled.
Shared links use a protected token that identifies the tenant and file. The token has no built-in expiration time; disabling sharing or deleting the file makes the link unavailable. Disabling sharing is not permanent link revocation: re-enabling the same file makes previously issued links valid again, and individual links cannot be revoked. Treat the URL as a secret. Persist the ASP.NET Core Data Protection key ring across restarts and deployments, and configure every application instance that serves these links to use the same key store and application name.
### Share URL Origin in Tiered Applications
MVC, Blazor and MudBlazor use a UI-specific option when they build copied share URLs. Configure the option when the HTTP API is hosted at a different public origin than the UI:
Use `FileManagementBlazorOptions` for the standard Blazor UI or `FileManagementBlazorMudBlazorOptions` for the MudBlazor UI. For copied share URLs, MVC falls back to the browser origin, while the Blazor UIs fall back to `NavigationManager.BaseUri`. These options only change copied share URLs. MVC authenticated downloads use the same-origin download endpoint; the Blazor UIs resolve the download origin from the File Management remote service configuration.
### Resource-Based Permissions
The module supports both module-wide permissions and resource permissions for individual directories and files. Users with a module-wide create, update, delete or view permission can perform that operation throughout File Management. A user without the corresponding module-wide permission can perform it when a matching resource permission is granted.
Directory resource permissions are inherited by descendants. For example, `View` on a directory grants view access to its descendant directories and files, while `Add` grants creation in that directory and its descendants. File-level `View`, `Edit`, `Move` and `Delete` grants apply to the selected file. Creating an item at the root still requires the module-wide create permission because the root is not a directory resource.
The `ManagePermissions` permissions show a **Permissions** action in the MVC, standard Blazor and Angular UIs. This action opens the Resource Permission Management UI for the selected directory or file. The MudBlazor UI does not currently provide this action. File sharing is controlled separately by `FileManagement.FileDescriptor.Share`; a resource permission does not grant sharing access.
### HTTP API and Download Tokens
The directory API is rooted at `/api/file-management/directory-descriptor` and exposes get, list, content, create, rename, move and delete operations. The file API is rooted at `/api/file-management/file-descriptor` and exposes list, upload pre-check, upload, content, rename, move, delete, storage information, download and sharing operations.
Rename and move inputs carry the descriptor's concurrency stamp. API clients should return the latest stamp received from a descriptor or directory-content response so concurrent changes are detected instead of silently overwritten.
Authenticated clients download a private file in two steps:
1. Call `GET /api/file-management/file-descriptor/download/{id}/token`. This operation checks the module-wide or resource `View` permission.
2. Navigate to `GET /api/file-management/file-descriptor/download/{id}?token=...`.
The download endpoint is anonymous because the token is the credential. A token is bound to one file and tenant, expires after 60 seconds and can be reused during that interval. Do not log or expose it. Public shared files use the separate anonymous `GET /api/file-management/file-descriptor/share?shareToken=...` endpoint.
## Data Seed
This module doesn't seed any data.
@ -162,7 +223,7 @@ This module doesn't seed any data.
This module follows the [Entity Best Practices & Conventions](../framework/architecture/best-practices/entities.md) guide.
##### TextTemplateContent
##### Directory and File Descriptors
- `DirectoryDescriptor` (aggregate root): Represents a folder.
- `FileDescriptor` (aggregate root): Represents a file.
@ -194,8 +255,15 @@ This module doesn't define any setting.
### Features
You can enable or disable this module for each tenant, also you can set maximum storage size for each tenant.
See the `FileManagementFeatures` class members for all features defined for this module.
You can enable or disable this module and set a maximum storage size for each tenant. The module defines these features:
- `FileManagement.Enable`: Enables the module. The default is `true`.
- `FileManagement.StorageSize`: Sets the numeric quota from `1` through `8000`. The default is `1`.
- `FileManagement.StorageSizeUnit`: Selects `Byte`, `Kilobyte`, `Megabyte`, `Gigabyte` or `Terabyte`. The default is `Terabyte`.
The default quota is therefore 1 TB. Usage is calculated from file descriptors in the current tenant context. An upload is rejected when the existing usage plus the incoming content reaches or exceeds the configured maximum.
Quota checking reads the current total before storing a file; it does not reserve capacity or lock concurrent uploads. If the quota is a strict security or billing boundary, serialize uploads for a tenant or add an application-level reservation mechanism around the upload operation.
### Application Layer
@ -204,6 +272,45 @@ See the `FileManagementFeatures` class members for all features defined for this
- `DirectoryDescriptorAppService` (implements `IDirectoryDescriptorAppService`): Implements the use cases of the file management UI.
- `FileDescriptorAppService` (implements `IFileDescriptorAppService`): Implements the use cases of the file management UI.
### File Icon Configuration
`FileIconOption` maps file extensions to Font Awesome classes or image URLs. Configure it in a module to add an extension, replace a built-in mapping or change the default icon:
```csharp
Configure<FileIconOption>(options =>
{
options.SetFileIcon(
"cad",
new FileIconInfo("fa-solid fa-cube", FileIconType.FontAwesome));
options.SetDefaultIcon(
new FileIconInfo("/images/file.svg", FileIconType.Url));
});
```
The MVC, standard Blazor and Angular UIs render the `IconInfo` returned by the application service and therefore use this configuration. The MudBlazor UI currently selects Material icons from the file extension and is not affected by `FileIconOption`.
### Extending the Entities
`DirectoryDescriptor` and `FileDescriptor` support the [Module Entity Extensions](../framework/architecture/modularity/extending/module-entity-extensions.md) system. Configure extra properties in the `Domain.Shared` project before the database model is created:
The module maps these extra properties through its extensible input and output DTOs and applies the corresponding EF Core object-extension mappings. Add the matching UI extension when the property must be editable or visible in a built-in UI.
### Database Providers
#### Common
@ -238,4 +345,14 @@ See the `FileManagementPermissions` class members for all permissions defined fo
## Distributed Events
This module doesn't define any additional distributed event. See the [standard distributed events](../framework/infrastructure/event-bus/distributed).
This module doesn't explicitly publish a custom distributed event. It defines `DirectoryDescriptorEto` and `FileDescriptorEto` mappings for ABP's standard distributed entity events. Automatic entity events are disabled by default; enable the selectors in the application that owns the File Management data when consumers need create, update or delete notifications:
This publishes the standard `EntityCreatedEto<T>`, `EntityUpdatedEto<T>` and `EntityDeletedEto<T>` envelopes with the corresponding ETO payload. See the [distributed event bus documentation](../framework/infrastructure/event-bus/distributed) for delivery and handler configuration.