Ledbim.Storage 1.2.0

dotnet add package Ledbim.Storage --version 1.2.0
                    
NuGet\Install-Package Ledbim.Storage -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ledbim.Storage" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ledbim.Storage" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Ledbim.Storage" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ledbim.Storage --version 1.2.0
                    
#r "nuget: Ledbim.Storage, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ledbim.Storage@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ledbim.Storage&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Ledbim.Storage&version=1.2.0
                    
Install as a Cake Tool

Ledbim.Storage

<p align="center"> <img src="ledbim_storage_logo.png" alt="Ledbim.Storage" width="120" /> </p>

<p align="center"> <strong>FTP Upload · Base64 · Stream · Otomatik Klasör · Public URL</strong><br/> Ledbim ekosistemi için dosya depolama altyapısı. </p>


Kapsam

Ledbim.Storage paketi şu bileşenleri sağlar:

Bileşen Açıklama
IFileService Dosya yükleme ve silme arayüzü
FileService FluentFTP tabanlı IIS FTP implementasyonu
FtpSettings Bağlantı ve public URL için tek adres yapılandırması
AddFileService() Tek satır DI kaydı

Kurulum

dotnet add package Ledbim.Storage

Bağımlılıklar

FluentFTP                                              v52.1.0
Microsoft.Extensions.Configuration.Abstractions        v10.0.0
Microsoft.Extensions.DependencyInjection.Abstractions  v10.0.0
Microsoft.Extensions.Options.ConfigurationExtensions   v10.0.0
Ledbim.Core                                           (project reference)

Hızlı Başlangıç

1. appsettings.json

{
  "FtpSettings": {
    "FtpAddress": "cdn.example.com",
    "Username": "ftpuser",
    "Password": "ftppassword"
  }
}

2. Program.cs

builder.Services.AddFileService(builder.Configuration);

3. Kullanım

public class UploadProfilePhotoCommandHandler(IFileService fileService)
    : IRequestHandler<UploadProfilePhotoCommand, Result<string>>
{
    public async Task<Result<string>> Handle(
        UploadProfilePhotoCommand request, CancellationToken ct)
    {
        var uploadRequest = new FileUploadRequest
        {
            Content = request.FileStream,
            FileName = request.FileName,
            Length = request.FileStream.Length,
            Folder = $"users/{request.UserId}/photos"
        };

        var result = await fileService.UploadAsync(uploadRequest, ct);

        return Result<string>.Success(ResultType.Success, result.Path);
    }
}

FtpAddress — Tek Alan, İki Görev

FtpAddress, hem FTP sunucusuna bağlantı kurmak hem de yüklenen dosyaların herkese açık HTTPS URL'sini oluşturmak için kullanılır.

FtpAddress = "cdn.example.com"
                │
                ├── FTP bağlantısı → ftp://cdn.example.com:21
                │
                └── Public URL    → https://cdn.example.com/uploads/image.jpg

Desteklenen Adres Formatları

{ "FtpAddress": "cdn.example.com" }
{ "FtpAddress": "ftp://cdn.example.com" }
{ "FtpAddress": "ftp://cdn.example.com:2121" }
{ "FtpAddress": "cdn.example.com:2121" }

Port belirtilmezse varsayılan 21 kullanılır.


IFileService

public interface IFileService
{
    // Stream ile yükleme
    Task<FileUploadResult> UploadAsync(
        FileUploadRequest request,
        CancellationToken cancellationToken = default);

    // Base64 ile yükleme
    Task<FileUploadResult> UploadBase64Async(
        Base64UploadRequest request,
        CancellationToken cancellationToken = default);

    // Silme
    Task RemoveAsync(
        string pathOrUrl,
        CancellationToken cancellationToken = default);
}

Upload — Stream

public sealed class FileUploadRequest
{
    public required Stream Content { get; init; }    // Dosya içeriği
    public required string FileName { get; init; }   // Özgün dosya adı (uzantı için kullanılır)
    public required long Length { get; init; }       // Bayt cinsinden dosya boyutu
    public required string Folder { get; init; }     // Hedef FTP klasörü
}
// IFormFile'dan
var request = new FileUploadRequest
{
    Content = formFile.OpenReadStream(),
    FileName = formFile.FileName,          // Uzantı buradan alınır
    Length = formFile.Length,
    Folder = "invoices/2024"
};

FileUploadResult result = await fileService.UploadAsync(request, ct);
// result.Path      → "https://cdn.example.com/invoices/2024/a1b2c3d4.pdf"
// result.Extension → ".pdf"
// result.SizeBytes → 204800
// result.SizeKb    → 200

Sunucuda dosya adı olarak {Guid}.{extension} formatı kullanılır — özgün dosya adı iletilmez.


Upload — Base64

public sealed class Base64UploadRequest
{
    public required string Base64Content { get; init; }   // Base64 veya Data URI
    public required string Folder { get; init; }          // Hedef FTP klasörü
    public string? Extension { get; init; }               // ".jpg", "jpg" — opsiyonel
}

Base64Content alanı hem saf Base64 hem de data URI formatını kabul eder — prefix otomatik temizlenir:

// Saf Base64
var request = new Base64UploadRequest
{
    Base64Content = "iVBORw0KGgoAAAANS...",
    Folder = "avatars",
    Extension = ".png"
};

// Data URI (mobil uygulamalar ve browser form'larından gelen format)
var request = new Base64UploadRequest
{
    Base64Content = "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
    Folder = "avatars"
    // Extension verilmezse uzantısız yüklenir
};

FileUploadResult result = await fileService.UploadBase64Async(request, ct);

Stream vs Base64 — hangisini seçmeli?

UploadAsync UploadBase64Async
Kaynak IFormFile, FileStream API body'den gelen JSON string, browser canvas
Boyut bilgisi Length gerekli Otomatik (byte array'den)
Dosya adı FileName'dan uzantı alınır Extension parametresinden

FileUploadResult

public sealed class FileUploadResult
{
    public required string Path { get; init; }     // HTTPS public URL
    public required string Extension { get; init; } // ".jpg", ".pdf" vb.
    public long SizeBytes { get; init; }            // Dosya boyutu (byte)
    public decimal SizeKb => SizeBytes / 1024m;     // Hesaplanan değer (KB)
}
var result = await fileService.UploadAsync(request, ct);

Console.WriteLine(result.Path);       // https://cdn.example.com/products/a1b2c3.jpg
Console.WriteLine(result.Extension);  // .jpg
Console.WriteLine(result.SizeBytes);  // 153600
Console.WriteLine(result.SizeKb);     // 150

Otomatik Klasör Oluşturma

Folder parametresinde belirtilen dizin yapısı FTP sunucusunda yoksa otomatik olarak oluşturulur. Her segment ayrı ayrı kontrol edilir:

Folder = "products/electronics/images"
              │
              ├── "products"             → yoksa oluştur
              ├── "products/electronics" → yoksa oluştur
              └── "products/electronics/images" → yoksa oluştur

Önceden klasör oluşturulması gerekmez — hem UploadAsync hem UploadBase64Async için otomatik çalışır.


Silme

// URL ile
await fileService.RemoveAsync("https://cdn.example.com/avatars/a1b2c3.jpg", ct);

// Göreli path ile
await fileService.RemoveAsync("avatars/a1b2c3.jpg", ct);

Güvenlik: Yalnızca FtpAddress'te tanımlı host'a ait dosyalar silinebilir. Farklı host belirtilirse metod sessizce döner — exception fırlatmaz.

Null/Boş değer: null veya boş string iletilirse metod sessizce döner.


Mimari Notlar

  • Her işlemde yeni FTP bağlantısı: FileService her upload/remove işleminde AsyncFtpClient oluşturur, bağlanır ve işlem sonrası bağlantıyı kapatır.
  • Download desteği yok: IFileService yalnızca upload ve silme işlemlerini kapsar. Dosya okuma için Path üzerinden HTTPS ile doğrudan erişim önerilir.
  • Exists kontrolü yok: IFileService'te public bir dosya varlık kontrolü metodu bulunmaz.
  • FTP credentials güvenliği: FtpAddress, Username ve Password değerlerini appsettings'te düz metin olarak tutmak yerine Secret Manager veya Azure Key Vault gibi güvenli kaynaklardan yönetin.

Lisans

Bu paket Ledbim Bilişim tarafından geliştirilmektedir. Ticari kullanım için lisans bilgisi için iletişime geçiniz.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 162 3/28/2026