Netigent.Utils.FileStoreIO
1.4.4
dotnet add package Netigent.Utils.FileStoreIO --version 1.4.4
NuGet\Install-Package Netigent.Utils.FileStoreIO -Version 1.4.4
<PackageReference Include="Netigent.Utils.FileStoreIO" Version="1.4.4" />
<PackageVersion Include="Netigent.Utils.FileStoreIO" Version="1.4.4" />
<PackageReference Include="Netigent.Utils.FileStoreIO" />
paket add Netigent.Utils.FileStoreIO --version 1.4.4
#r "nuget: Netigent.Utils.FileStoreIO, 1.4.4"
#:package Netigent.Utils.FileStoreIO@1.4.4
#addin nuget:?package=Netigent.Utils.FileStoreIO&version=1.4.4
#tool nuget:?package=Netigent.Utils.FileStoreIO&version=1.4.4
FileStoreIOClient
A generic layer to allow the saving and loading of files from configurable stores using a unique fileRef with prefix code for detection in your code.
Supports UNC (FileSystem), Database, Box, and AWS S3 Buckets.
License
This library is licensed under the Apache License 2.0.
- Full commercial use is allowed (including in closed-source products, SaaS, or sold software — no royalties or source-sharing required).
- Explicit patent grant from contributors for any patents necessarily infringed by their contributions.
- Strong disclaimers: Provided "AS IS", WITHOUT WARRANTIES of any kind (express or implied). Use at your own risk — no liability for any damages.
- Full license text: LICENSE (in the repository root).
Contributions you make are automatically licensed under the same Apache 2.0 terms.
How to Use
Thanks for considering this library — we hope it saves you time and simplifies file handling!
The library supports multiple storage providers (Database, FileSystem/UNC, Box, AWS S3) and uses a consistent fileRef (e.g., _$uniqueid) for all operations.
Database Notes
The library auto-creates and upgrades the FileStoreIndex table in the specified schema.
You can safely drop unused legacy columns: [FileType], [MainGroup], [SubGroup], [PathTags] — they are no longer used.
Quick Start
Direct Usage (keeping last 3 versions)
// Example configuration objects (use your real values!)
var myBoxConfig = new BoxConfig { /* ... your Box settings ... */ };
var myS3Config = new S3Config { /* ... your S3 settings ... */ };
var myFsConfig = new FileSystemConfig { RootFolder = @"C:\temp\Files\", StoreFileAsUniqueRef = false };
var fileStoreIOClient = new FileStoreIOClient(
appPrefix: "MyApp",
databaseConnection: "Server=.;Database=myDb;Trusted_Connection=True;",
maxVersions: 3,
dbSchema: "filestore",
defaultFileStore: FileStorageProvider.FileSystem, // or S3, Database, Box
boxConfig: myBoxConfig,
s3Config: myS3Config,
fileSystemConfig: myFsConfig);
// Example: Get a file by ref
var file = await fileStoreIOClient.File_GetAsyncV2("_$23fe627c5a5b410aa6017db308b71077");
Using Dependency Injection (recommended for ASP.NET Core)
appSettings.json example (keeping last 5 versions)
"FileStoreIO": {
"Database": "Server=.;Database=myDatabase;UID=mySa;PWD=myPassword;",
"AppPrefix": "MyAppToScopeTo",
"FilePrefix": "_$",
"DatabaseSchema": "filestore",
"MaxVersions": 5,
"DefaultStorage": "S3",
"S3": {
"AccessKey": "ExampleAccessKey",
"SecretKey": "mysecretkeyinhere+",
"Region": "us-west-2",
"BucketName": "my-example-bucket-name"
},
"Box": {
"EnterpriseID": "123456789",
"AutoCreateRoot": false,
"TimeoutInMins": 15,
"BoxAppSettings": {
"ClientID": "exampleid12345",
"ClientSecret": "examplesecret12345",
"AppAuth": {
"Passphrase": "examplepassphrase12345",
"PrivateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nEXAMPLEEXAMPLEEXAMPLE\n-----END ENCRYPTED PRIVATE KEY-----\n",
"PublicKeyID": "abc1234"
}
}
},
"FileSystem": {
"RootFolder": "c:\\temp\\files\\",
"StoreFileAsUniqueRef": false
}
}
Registering in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Inject FileStoreIOClient provider
services.Configure<FileStoreIOConfig>(Configuration.GetSection(FileStoreIOConfig.Section));
services.AddSingleton<Netigent.Utils.FileStoreIO.IFileStoreIOClient, FileStoreIOClient>();
}
Usage in a Controller Example
using Netigent.Examples.UploadApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Netigent.Utils.FileStoreIO;
using Netigent.Utils.FileStoreIO.Enums;
using System.Threading.Tasks;
namespace Netigent.Examples.UploadApp.Controllers
{
public class HomeController : Controller
{
private readonly IFileStoreIOClient _ioClient;
public HomeController(IFileStoreIOClient fileStoreIOClient)
{
_ioClient = fileStoreIOClient;
}
public async Task<IActionResult> Index()
{
ViewBag.Message = TempData["Message"];
return View(new FileUploadViewModel { Files = await _ioClient.Files_GetAll() });
}
[HttpPost]
[ActionName("Upload")]
public async Task<IActionResult> Upload(IFormFile selectedFile, string location = "database", string description = "", string customerCode = "", string itemType = "")
{
var uploadLocation = (location ?? "").Equals("Database", StringComparison.CurrentCultureIgnoreCase)
? FileStorageProvider.Database
: FileStorageProvider.FileSystem;
var uploadedCode = await _ioClient.File_UpsertAsync(selectedFile, uploadLocation, description: description, customerCode, itemType);
TempData["Message"] = $"File successfully uploaded to {uploadLocation} {uploadedCode}";
// Setting success properties
TempData["FileId"] = uploadedCode;
TempData["FileLink"] = $"https://localhost:44317/Home/GetFile/{uploadedCode}";
// Example: render dynamic images from FileStoreIOClient
// e.g. <img src="@TempData["FileLink"]" style="height: 100px; width: auto;" />
return RedirectToAction("Index");
}
public async Task<IActionResult> GetFile(string id)
{
var file = await _ioClient.File_Get(id);
if (file == null) return NotFound();
return File(file.Data, file.ContentType, file.Name);
}
public async Task<IActionResult> DeleteFile(string id)
{
// var xyz = await something(); // Remove or replace placeholder
var fileInfo = await _ioClient.File_DeleteAsync(id);
return RedirectToAction("Index");
}
}
}
Version History Highlights
1.4.4
Fixed License link in README.
1.4.3
Fixed License link in README.
1.4.2
Added MimeType helper for SVG = image/svg+xml (see changes in 1.4.0).
1.4.1
Bug fix on absolute paths in FileSystem storage (see changes in 1.4.0).
1.4.0
- Marked old methods as obsolete:
Use these clearer alternatives instead:List<InternalFileModel> Files_GetAllV2(string[] pathTags, bool recursiveSearch = false); List<InternalFileModel> Files_GetAllV2(string relationalFilePathAndName, bool recursiveSearch = false);List<FileStoreItem> Files_GetByFolder(string folderPath, bool includeSubFolders = false); List<FileStoreItem> Files_GetByFileAndFolder(string folderPath, bool includeSubFolders, string fileToFind, bool exactFileMatch); - Removed
Microsoft.AspNetCore.Http.Featuresdependency (Upsert methods forIFormFileremoved — usebyte[]directly):IFormFile myFile = ...; // from HttpRequest using var dataStream = new MemoryStream(); await myFile.CopyToAsync(dataStream); string fileRef = await fileStoreIOClient.File_UpsertAsyncV2("HT/Training/myprocedures.pdf", dataStream.ToArray()); - Renamed models for clarity:
FileObjectModel→FileOutput(simple output for sending to clients)
InternalFileModel→FileStoreItem(full record fromFileStoreIndextable) FileStoreIndextable now usesFoldercolumn (PathTagsdeprecated but kept for reference).
1.3.0
Added support for relocating files:
Task<ResultModel> File_MoveAsync(string fileRef, string[] pathTags);
Task<ResultModel> File_MoveAsync(string fileRef, string relationalFilePathAndName);
1.2.1
Bug fix: Subfile replaced by single Parent. RecursiveSearch = false is now default.
1.2.0
Added recursive flag to Files_GetAllV2. Removed obsolete legacy methods.
1.1.7
Bug fix for AppPrefix not populating correctly. Upgraded to .NET 8.0 LTS + package updates.
1.1.6
Database migration: Include AppPrefix in PathTags (run this SQL if files "disappeared" after v1.1.5):
UPDATE {schema}.[FileStoreIndex]
SET PathTags = '{AppPrefix}/' + PathTags
WHERE PathTags NOT LIKE '{AppPrefix}%';
1.1.5
README updates and stabilization.
1.1.4
Internal database upgrade.
1.1.3
Added README.md to NuGet package.
(Older versions omitted for brevity — see commit history for full details.)
Contributing
Contributions are very welcome — from individuals, companies, bug hunters, feature requesters, and documentation helpers alike!
This project uses Apache 2.0 with an explicit patent grant, so companies can contribute safely with mutual patent protection.
How to contribute:
- Fork https://github.com/netigent/file-store-io
- Create a branch:
git checkout -b feature/my-cool-change - Make your changes + add tests if possible
- Push and open a Pull Request
We especially appreciate:
- Support for new storage providers
- Performance improvements
- Better error handling / logging
- Documentation / examples
- Bug fixes
Open an issue first for big changes or questions.
Thanks in advance — your help makes this library better for everyone!
Questions / Issues
Found a bug? Have a feature idea?
→ Open an issue here: https://github.com/netigent/file-store-io/issues
Enjoy using FileStoreIOClient!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- AWSSDK.S3 (>= 3.7.412.4)
- BouncyCastle.Cryptography (>= 2.5.0)
- Dapper (>= 2.1.66)
- Microsoft.Extensions.Options (>= 8.0.2)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SqlClient (>= 4.9.0)
- System.IdentityModel.Tokens.Jwt (>= 8.3.1)
-
net10.0
- AWSSDK.S3 (>= 3.7.412.4)
- BouncyCastle.Cryptography (>= 2.5.0)
- Dapper (>= 2.1.66)
- Microsoft.Extensions.Options (>= 10.0.2)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SqlClient (>= 4.9.0)
- System.IdentityModel.Tokens.Jwt (>= 8.3.1)
-
net8.0
- AWSSDK.S3 (>= 3.7.412.4)
- BouncyCastle.Cryptography (>= 2.5.0)
- Dapper (>= 2.1.66)
- Microsoft.Extensions.Options (>= 8.0.2)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SqlClient (>= 4.9.0)
- System.IdentityModel.Tokens.Jwt (>= 8.3.1)
-
net9.0
- AWSSDK.S3 (>= 3.7.412.4)
- BouncyCastle.Cryptography (>= 2.5.0)
- Dapper (>= 2.1.66)
- Microsoft.Extensions.Options (>= 9.0.12)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SqlClient (>= 4.9.0)
- System.IdentityModel.Tokens.Jwt (>= 8.3.1)
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.4.4 | 126 | 1/31/2026 |
| 1.4.3 | 114 | 1/23/2026 |
| 1.4.2 | 102 | 1/23/2026 |
| 1.4.1 | 228 | 12/5/2025 |
| 1.4.0 | 207 | 11/27/2025 |
| 1.3.1 | 215 | 10/28/2025 |
| 1.3.0 | 297 | 8/6/2025 |
| 1.2.1 | 312 | 5/20/2025 |
| 1.2.0 | 207 | 1/24/2025 |
| 1.1.7 | 180 | 1/23/2025 |
| 1.1.6 | 272 | 2/17/2024 |
| 1.1.5 | 239 | 2/15/2024 |
| 1.1.4 | 203 | 2/15/2024 |
| 1.1.3 | 208 | 2/15/2024 |
| 1.1.2 | 210 | 2/15/2024 |
| 1.1.1 | 217 | 2/15/2024 |
| 1.0.14 | 1,619 | 6/2/2023 |
| 1.0.13 | 342 | 3/30/2023 |
| 1.0.12 | 328 | 3/30/2023 |
| 1.0.11 | 367 | 3/16/2023 |
Switched license to Apache 2.0 (explicit patent grant, stronger disclaimers). See README for full changelog and contribution guidelines.