Published on

dotnet file upload with ABP Blob store and Minio

Table of Contents

Intro

In this post we will implement file upload using the ABP blob store and Minio

Create a new project

abp new FileUpload

Create a container

Create the container in Domain project.

Install Volo.Abp.BlobStoring NuGet package to your Domain project

[BlobContainerName("document")]
public class DocumentContainer
{
}

Create the Entity and Entity Dto

Create the Entity in Domain project.

public class Document : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
    public long FileSize { get; set; }

    public string MimeType { get; set; }

    public Guid? TenantId { get; set; }

    protected Document()
    {
    }

    public Document(
        Guid id,
        long fileSize,
        string mimeType,
        Guid? tenantId
    ) : base(id)
    {
        FileSize = fileSize;
        MimeType = mimeType;
        TenantId = tenantId;
    }
}

Create EntityDto in Contracts project

public class DocumentDto : EntityDto<Guid>
{
    public long FileSize { get; set; }

    public string FileUrl { get; set; }

    public string MimeType { get; set; }
}

Add mapping for the Entity and Dto in the ApplicationAutoMapperProfile class in the Application project

CreateMap<Document, DocumentDto>().ReverseMap();

Add entity to the DBContext

Add DbSet

public DbSet<Document> Documents { get; set; }

Configure Ef core

builder.Entity<Document>(b =>
{
    b.ToTable(FileUploadConsts.DbTablePrefix + "Document", FileUploadConsts.DbSchema);
    b.ConfigureByConvention();
});

Add migration and update the database

To create ef migration

dotnet ef migrations add "added_documents"

To update the database

dotnet ef database update

Configure Minio

Install Volo.Abp.BlobStoring.Minio NuGet package to your Web and add [DependsOn(typeof(AbpBlobStoringMinioModule))] to the Web Module

Configuration is done in the ConfigureServices method of your module class

Configure<AbpBlobStoringOptions>(options =>
{
    options.Containers.ConfigureDefault(container =>
    {
        container.UseMinio(minio =>
        {
            minio.EndPoint = "localhost:9900"; // your minio endPoint
            minio.AccessKey = "AKIAIOSFODNN7EXAMPLE"; // your minio accessKey
            minio.SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"; // your minio secretKey
            minio.BucketName = "test1"; // your minio bucketName
        });
    });
});

Create Document AppService

The app service will have 2 methods one is to upload the files and another one is to view the files.

public class DocumentAppService : FileUploadAppService
{
    private readonly IBlobContainer<DocumentContainer> _blobContainer;
    private readonly IRepository<Document, Guid> _repository;
    public DocumentAppService(IRepository<Document, Guid> repository, IBlobContainer<DocumentContainer> blobContainer)
    {
        _repository = repository;
        _blobContainer = blobContainer;
    }

    public async Task<List<DocumentDto>> Upload([FromForm] List<IFormFile> files)
    {
        var output = new List<DocumentDto>();
        foreach (var file in files)
        {
            using var memoryStream = new MemoryStream();
            await file.CopyToAsync(memoryStream).ConfigureAwait(false);
            var id = Guid.NewGuid();
            var newFile = new Document(id, file.Length, file.ContentType, CurrentTenant.Id);
            var created = await _repository.InsertAsync(newFile);
            await _blobContainer.SaveAsync(id.ToString(), memoryStream.ToArray()).ConfigureAwait(false);
            output.Add(ObjectMapper.Map<Document, DocumentDto>(newFile));
        }

        return output;
    }

    public async Task<FileResult> Get(Guid id)
    {
        var currentFile = _repository.FirstOrDefault(x => x.Id == id);
        if (currentFile != null)
        {
            var myfile = await _blobContainer.GetAllBytesOrNullAsync(id.ToString());
            return new FileContentResult(myfile, currentFile.MimeType);
        }

        throw new FileNotFoundException();
    }
}

Repo Link : https://github.com/antosubash/FileUpload