EasyDatabaseManager 1.1.1
dotnet add package EasyDatabaseManager --version 1.1.1
NuGet\Install-Package EasyDatabaseManager -Version 1.1.1
<PackageReference Include="EasyDatabaseManager" Version="1.1.1" />
<PackageVersion Include="EasyDatabaseManager" Version="1.1.1" />
<PackageReference Include="EasyDatabaseManager" />
paket add EasyDatabaseManager --version 1.1.1
#r "nuget: EasyDatabaseManager, 1.1.1"
#:package EasyDatabaseManager@1.1.1
#addin nuget:?package=EasyDatabaseManager&version=1.1.1
#tool nuget:?package=EasyDatabaseManager&version=1.1.1
Easy Database Manager
A lightweight, self-contained SQL data explorer for ASP.NET Core, delivered as a single NuGet package with a simple two-line registration. Browse, search, filter, and edit your database tables through a built-in web UI — without adding Entity Framework Core, without a DbContext, and without any ORM dependency.
Easy Database Manager works with SQL Server, PostgreSQL, MySQL, and SQLite.
Table of contents
- Why Easy Database Manager
- Feature highlights
- UI overview
- Requirements
- Installation
- Database providers
- Quick start
- Configuration reference
- Column visibility and editability rules
- Soft-delete support
- Filtering, sorting, and search
- UI features
- Security guidance
- Advanced scenarios
- Troubleshooting
- FAQ
- Contact support
- Author
- License
Why Easy Database Manager
Most teams eventually need a way to look inside the database from a running ASP.NET Core application — to verify a migration, inspect a support ticket, fix a stuck row, or sanity-check an import. The usual options are heavy: deploy a separate admin tool, expose EF Core scaffolding, or ship a custom CRUD UI.
Easy Database Manager is the small, pragmatic middle ground:
- Drop it in. Two lines in
Program.csand you have a working table browser at/dev/easy-database-manager. - Zero ORM baggage. No
DbContext, no migrations, no model-first assumptions. Any existing schema works as-is. - Cross-database. One experience across SQL Server, PostgreSQL, MySQL, and SQLite.
- Safe by default. Hidden columns, masked secrets, read-only key and audit columns, and an explicit toggle for write access.
- Self-contained. No static files to copy, no CDN, no JavaScript build step.
Intended use cases: internal admin panels, developer and staging tooling, support dashboards, and debugging surfaces inside existing ASP.NET Core apps.
Feature highlights
Core
- No EF Core, no
DbContext, no ORM required. - Four database engines supported out of the box: SQL Server, PostgreSQL, MySQL, SQLite.
- Minimal setup — a single
AddEasyDatabaseManagercall at registration and a singleMapEasyDatabaseManagercall to expose the UI. - Fully configurable route prefix, page sizes, and column policies.
Data access and safety
- Hidden columns — never reach the UI.
- Masked columns — displayed as
••••••••; the value is revealed only on an explicit reveal request and is never included in search. - Read-only columns — excluded from updates (primary keys, identity columns, and computed columns are protected automatically;
Idis read-only by default, and you can add more viaReadOnlyColumns). - Global write toggle —
EnableWriteOperationsdisables all edits with a single flag. - Soft-delete filtering —
All,ActiveOnly,DeletedOnly; works with both boolean-style and nullable-date-style delete markers.
UI
- Built-in web UI, delivered with the package — nothing to deploy separately.
- Responsive layout with collapsible sidebar, mobile-friendly design, and light / dark themes.
- Global search across visible, non-masked columns.
- Column-level filters with operators:
eq,ne,gt,gte,lt,lte,contains,startsWith,endsWith,isnull,notnull. - Sortable headers and server-side pagination with configurable page sizes.
- Inline cell editing with confirm / cancel and server-side validation.
- Record deletion — a per-row delete button (shown only when writes are enabled) performs a permanent
DELETE, gated byEnableWriteOperationsand a primary key. - Record detail view for a single row across all visible columns.
- Session-persisted state — the last table, page, filters, and sort survive a reload.
- Browser history integration — navigating between tables pushes history entries, so the browser Back button returns to the previous table.
UI overview
Once enabled, the UI is available at your configured route prefix (default /dev/easy-database-manager) and surfaces:
- a sidebar listing every table the connection can see, with live search;
- a query pane with global search, filter builder, include-deleted toggle, and page-size selector;
- a results grid with sortable headers and editable cells (when write mode is on);
- a record detail panel that opens the full row across all visible columns;
- a theme toggle and mobile-friendly collapsible sidebar.
Requirements
- .NET 6.0, 7.0, 8.0, 9.0, or 10.0
- ASP.NET Core (any hosting model: Kestrel, IIS, reverse-proxy, container)
- A supported database and its ADO.NET provider package (see below)
Installation
dotnet add package EasyDatabaseManager
Or via the Package Manager Console:
Install-Package EasyDatabaseManager
Database providers
Easy Database Manager intentionally does not depend on any specific database provider. Install the provider that matches your database:
| Engine | Recommended provider |
|---|---|
| SQL Server | Microsoft.Data.SqlClient |
| PostgreSQL | Npgsql |
| MySQL | MySqlConnector (preferred) or MySql.Data |
| SQLite | Microsoft.Data.Sqlite |
Example:
dotnet add package Microsoft.Data.SqlClient
# or
dotnet add package Npgsql
# or
dotnet add package MySqlConnector
# or
dotnet add package Microsoft.Data.Sqlite
The provider only needs to be referenced by your host application.
Quick start
using EasyDatabaseManager.Configuration;
using EasyDatabaseManager.Endpoints;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEasyDatabaseManager(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection")!;
options.DatabaseType = DatabaseType.SqlServer;
// UI/route
options.RoutePrefix = "/dev/easy-database-manager";
options.EnableWriteOperations = true;
options.DefaultPageSize = 25;
options.MaxPageSize = 200;
// Soft delete
options.SoftDeleteColumn = "IsValid";
// Column-level controls
options.HiddenColumns.Add("PasswordHash");
options.HiddenColumns.Add("RefreshToken");
options.MaskedColumns.Add("ApiKey");
options.MaskedColumns.Add("PrivateKey");
options.MaskedColumns.Add("SecretKey");
options.ReadOnlyColumns.Add("TenantId");
});
var app = builder.Build();
// (Optional) protect the explorer behind your own auth.
app.UseAuthentication();
app.UseAuthorization();
app.MapEasyDatabaseManager();
app.Run();
Open the browser at:
https://<your-host>/dev/easy-database-manager
That's it. No scaffolding, no migrations, no static files to copy.
Configuration reference
All options are configured inside the AddEasyDatabaseManager(options => { ... }) delegate.
| Option | Default | Description |
|---|---|---|
ConnectionString |
required | Connection string used to reach your database. |
DatabaseType |
SqlServer |
One of SqlServer, PostgreSql, MySql, Sqlite. |
RoutePrefix |
/dev/easy-database-manager |
Route prefix for the UI. |
EnableWriteOperations |
true |
Master toggle for edits. When false, all update operations are rejected. |
DefaultPageSize |
25 |
Default rows per page. |
MaxPageSize |
200 |
Hard upper bound on page size. |
AccessKey |
null |
Optional access key (min 16 chars). Used when Users is empty. |
Users |
empty | Dictionary<string,string> of username → password. Enables username/password login. Takes precedence over AccessKey. |
SessionSecret |
null |
HMAC key for session cookies. If null, a random 32-byte key is generated per process. |
AccessSessionDuration |
8 hours |
How long an unlocked session stays valid. |
SoftDeleteColumn |
null |
Name of the soft-delete column (e.g. DeletedAt, IsActive, IsValid). Enables soft filtering. |
HiddenColumns |
empty | Column names to hide completely (case-insensitive). |
MaskedColumns |
empty | Column names to display as •••••••• (case-insensitive). |
ReadOnlyColumns |
{ "Id" } |
Additional column names to mark as non-editable. |
SchemaCacheDuration |
5 minutes |
How long table and column metadata stay cached between requests. |
Default read-only columns
Only Id is treated as read-only out of the box. Add any other columns you want protected — for example audit fields like CreatedAt / UpdatedBy — via options.ReadOnlyColumns.
In addition, primary keys, identity / auto-increment columns, and computed columns are always protected from edits automatically.
Column visibility and editability rules
Every column follows three orthogonal rules:
1. Hidden
Hidden columns are completely removed from the UI — they do not appear in the grid, the record detail, or search results.
options.HiddenColumns.Add("PasswordHash");
2. Masked
Masked columns are shown as ••••••••. The column name remains visible so users know it exists, and the value is revealed only on an explicit reveal request.
options.MaskedColumns.Add("ApiKey");
3. Read-only
Read-only columns are displayed normally but cannot be updated. The following are read-only automatically:
- every column in
options.ReadOnlyColumns - primary keys
- identity / auto-increment columns
- computed columns
- hidden columns
options.ReadOnlyColumns.Add("TenantId");
Authentication
The explorer supports three modes, chosen automatically:
| Mode | Configuration | Login UI |
|---|---|---|
| Open | Neither Users nor AccessKey set |
No login screen. |
| Access key | AccessKey set, Users empty |
Single password field. |
| Users | Users has one or more entries |
Username + password form. |
Users takes precedence if both are configured.
Username + password
options.Users["alice"] = "change-me-plz"; // plaintext, hashed at startup
options.Users["bob"] = "pbkdf2:100000:<salt>:<hash>"; // pre-hashed, used as-is
options.AccessSessionDuration = TimeSpan.FromHours(4);
options.SessionSecret = "a-long-random-string-for-cookies"; // optional, otherwise random per process
Passwords are hashed with PBKDF2-HMAC-SHA256 (100,000 iterations, per-user random salt) at startup. The plaintext entries in Users are replaced with their hashed form after Validate() runs, so nothing is stored in plain memory afterward. You can supply already-hashed values (prefix pbkdf2:…) if you prefer to keep plaintext out of your config entirely.
Login issues an HttpOnly, SameSite=Strict cookie (Secure on HTTPS) signed with an HMAC over the subject using SessionSecret. Rotate SessionSecret (or change any password) to invalidate all existing sessions.
Access key (single-admin fallback)
options.AccessKey = "change-me-to-a-long-random-string";
A single shared secret, minimum 16 characters. Shown as a password field on the lock screen.
Security notes
- Treat whatever holds your
Users/AccessKeylike a secret (appsettings.json, environment variables, a secret manager). - The explorer does not rate-limit or lock out failed logins — put it behind a reverse proxy with rate limits if it's exposed to the internet.
- Mask-reveal and cell edits are allowed for any authenticated user; there are no per-user permissions.
Soft-delete support
Set options.SoftDeleteColumn to enable soft-delete filtering in the UI.
options.SoftDeleteColumn = "DeletedAt"; // or "IsActive", "IsValid", etc.
The explorer supports three modes:
| Mode | Meaning |
|---|---|
All |
Return all rows regardless of delete flag. |
ActiveOnly |
Return only non-deleted rows. (default) |
DeletedOnly |
Return only deleted rows. |
Both boolean-style markers and nullable date markers are supported:
- Boolean columns (
IsActive,IsValid, etc.) follow the conventiontrue = active,false/NULL = deleted. - Nullable date columns (
DeletedAt, etc.) follow the conventionNULL = active, non-null = deleted.
Tables that do not expose the configured soft-delete column are treated as hard-delete tables automatically.
Filtering, sorting, and search
Global search
The search box performs a case-insensitive contains-match across all visible, non-masked columns (each is cast to text for matching). Masked and hidden columns are never searched.
Column filters
From the filter builder, add one or more rules using the following operators:
| Operator | Behavior |
|---|---|
eq |
Equals (or IS NULL when no value is provided). |
ne |
Not equal. |
gt, gte |
Greater than / greater-or-equal. |
lt, lte |
Less than / less-or-equal. |
contains |
Text contains. |
startsWith |
Text starts with. |
endsWith |
Text ends with. |
isnull |
Column value is null. |
notnull |
Column value is not null. |
Sorting
Click any visible column header to sort. Click again to reverse the direction.
Pagination
Page size is selectable from the UI and clamped to the configured MaxPageSize.
UI features
- Table sidebar with live search and responsive collapsing.
- Global search box across visible text columns.
- Filter builder — add multiple column filters with typed operators.
- Sortable headers for every visible column.
- Include-deleted toggle (visible only when
SoftDeleteColumnis configured). - Page-size selector with configurable upper bound.
- Inline cell editing with confirm / cancel and server-side validation.
- Per-row delete button with a confirm prompt — performs a permanent
DELETE; visible only whenEnableWriteOperationsis on and the table has a primary key. - Record detail panel with a one-click open-from-row action.
- Session-persisted state — the current table, sort, filters, and page survive a page reload.
- Browser history integration — each table selection pushes a history entry, so the browser Back button navigates to the previous table; Forward restores the next one.
- Light and dark themes with persistent preference.
Security guidance
Easy Database Manager exposes a powerful surface over your database. Do not expose it to the public internet without authentication. Recommended practices:
- Gate the route behind auth.
MapEasyDatabaseManagerworks with the standard ASP.NET Core auth pipeline — add your own[Authorize]policy via endpoint conventions, a minimal-API filter, or a middleware in front of the route prefix. - Use a dedicated connection string scoped to the permissions this tool actually needs.
- Disable writes in production unless you have a specific reason otherwise:
options.EnableWriteOperations = app.Environment.IsDevelopment(); - Hide secrets. Add columns like
PasswordHash,RefreshToken,PrivateKey, or anything PII-sensitive toHiddenColumns. - Mask what must remain visible. Use
MaskedColumnsfor things likeApiKeywhere the existence matters but the value must not leak. - Put it under a non-obvious route in production, e.g.
/internal/_admin/db-<random>. - Put it behind your VPN / private network when possible.
Example — bind the explorer behind an authorization policy:
app.MapGroup("")
.RequireAuthorization("DbExplorerAccess")
.MapEasyDatabaseManager();
Advanced scenarios
Multiple environments, single config
builder.Services.AddEasyDatabaseManager(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection")!;
options.DatabaseType = DatabaseType.PostgreSql;
options.EnableWriteOperations = !builder.Environment.IsProduction();
options.RoutePrefix = builder.Environment.IsProduction()
? "/internal/ops/db"
: "/dev/easy-database-manager";
});
SQLite for a self-contained diagnostics page
builder.Services.AddEasyDatabaseManager(options =>
{
options.ConnectionString = $"Data Source={Path.Combine(app.Environment.ContentRootPath, "diagnostics.db")}";
options.DatabaseType = DatabaseType.Sqlite;
options.RoutePrefix = "/diagnostics/db";
});
Tuning metadata caching
For very dynamic schemas, lower SchemaCacheDuration; for stable production schemas, raise it:
options.SchemaCacheDuration = TimeSpan.FromMinutes(30);
Troubleshooting
The application fails to start with a connection-string error.
ConnectionString was not set in the AddEasyDatabaseManager delegate. Set it before the app starts.
Tables list is empty.
The database user used by the connection string does not have permission to read the schema catalog. Grant the equivalent of VIEW DEFINITION / metadata-read on the target schema.
Updates are rejected with 400. Check, in order:
EnableWriteOperationsistrue.- The table has a primary key.
- The target column is not hidden, read-only, identity, computed, or a primary key.
The UI loads but requests are denied. The route is behind an auth policy you haven't satisfied. Authenticate, or relax the policy for the relevant environment.
Cannot connect to the database. Confirm the matching ADO.NET provider package is installed in the host application, the connection string is valid, and the database is reachable from the host.
FAQ
Does it need Entity Framework Core?
No. Easy Database Manager does not require — or interact with — any EF Core DbContext.
Does it generate migrations or scaffolding? No. It reads your existing schema; it does not create, alter, or drop tables.
Can I use it against a read replica?
Yes. Point the connection string at the replica and set EnableWriteOperations = false.
How does it handle large tables?
Results are paged server-side. MaxPageSize caps how many rows a single page can contain.
Can I restrict which tables are visible?
Visibility is controlled by your database user's permissions. Grant SELECT only on the tables you want visible, and use HiddenColumns / MaskedColumns for fine-grained column control.
How do I stop users from editing a specific column?
Add the column to ReadOnlyColumns, or mark it as Hidden or Masked depending on whether it should be visible at all.
Can I change the URL where the UI is served?
Yes — set options.RoutePrefix to any path you want.
Does the UI require any external resources (CDN, fonts, etc.)? No. The UI is delivered by the package and loads without external dependencies.
Contact support
For support, bug reports, feature requests, or setup questions related to Easy Database Manager, please contact:
✉️ Email: ahmadalkasem371@gmail.com
When reporting an issue, please include:
- Package version
- .NET version
- Database provider used
- Error message or logs
- Steps to reproduce the issue
This helps resolve problems faster.
Author
Ahmad Alkasem Software Engineer · .NET Expert ✉️ ahmadalkasem371@gmail.com
Easy Database Manager is designed, developed, and maintained by Ahmad Alkasem. For commercial inquiries, licensing questions, support, or custom integrations, please reach out via email.
License
Easy Database Manager is released under the MIT License. © Ahmad Alkasem. You are free to use, copy, modify, and distribute this package, in whole or in part, subject to the terms of the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.