Superdev.AspNetCore provides reusable, low-dependency building blocks for ASP.NET Core applications. It focuses on pragmatic infrastructure code which can be shared across projects.
This library is available on NuGet: https://www.nuget.org/packages/Superdev.AspNetCore Use the following command to install Superdev.AspNetCore using NuGet package manager console:
PM> Install-Package Superdev.AspNetCore
You can use this library in ASP.NET Core projects compatible to .NET 9 and higher.
tbd
The following documentation covers the reusable building blocks that are already available in this package.
AuthorizeClaimAttribute allows you to protect endpoints based on the existence or value of claims.
Require a claim to exist:
using Superdev.AspNetCore.Security;
[AuthorizeClaim("permission")]
[HttpGet("profile")]
public IActionResult GetProfile()
{
return this.Ok();
}Require a specific claim value:
using Superdev.AspNetCore.Security;
[AuthorizeClaim("permission", "admin")]
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
return this.NoContent();
}Use more advanced matching with ClaimRequirementType:
using Superdev.AspNetCore.Security;
[AuthorizeClaim(ClaimRequirementType.Any, "permission", "read", "write")]
[HttpGet]
public IActionResult Get()
{
return this.Ok();
}Use writable options when a configuration section should be available through the regular options pipeline and should also be updateable at runtime.
ConfigureWritable<T>:
- binds the configuration section to the standard options infrastructure
- registers
IWritableOptions<T>for the same section - persists updates back to
appsettings.jsonby default
IWritableOptions<T> extends IOptionsSnapshot<T>, so you can still read the current value via Value or Get(name), and you also get write operations such as UpdateAsync(...) and UpdatePropertyAsync(...).
Register writable options:
using Superdev.AspNetCore.Options;
builder.Services.ConfigureWritable<MyFeatureOptions>(
builder.Configuration.GetSection("MyFeature"));Use a different file if needed:
using Superdev.AspNetCore.Options;
builder.Services.ConfigureWritable<MyFeatureOptions>(
builder.Configuration.GetSection("MyFeature"),
"appsettings.Development.json");Update options at runtime:
using Microsoft.AspNetCore.Mvc;
using Superdev.AspNetCore.Options;
public class MyController : ControllerBase
{
private readonly IWritableOptions<MyFeatureOptions> options;
public MyController(IWritableOptions<MyFeatureOptions> options)
{
this.options = options;
}
[HttpPost("enable")]
public async Task<IActionResult> EnableAsync()
{
await this.options.UpdatePropertyAsync(x => x.Enabled, true);
return this.Ok();
}
}Update multiple values in one operation:
await this.options.UpdateAsync(current =>
{
current.Enabled = true;
current.RefreshIntervalInMinutes = 5;
});Use regular options for read-only scenarios and IWritableOptions<T> only where runtime persistence is actually required.
Warning
Writable options modify the configured JSON file on disk. Use this feature intentionally and avoid exposing it through unprotected endpoints.
This package contains lightweight abstractions for system services which make business code easier to test.
Inject IDateTime:
using Superdev.AspNetCore.Services;
public class TokenService
{
private readonly IDateTime dateTime;
public TokenService(IDateTime dateTime)
{
this.dateTime = dateTime;
}
public DateTime GetExpirationUtc()
{
return this.dateTime.UtcNow.AddHours(1);
}
}Inject IFileSystem:
using Superdev.AspNetCore.Services;
public class DocumentService
{
private readonly IFileSystem fileSystem;
public DocumentService(IFileSystem fileSystem)
{
this.fileSystem = fileSystem;
}
public Task<string> ReadAsync(string path)
{
return this.fileSystem.ReadAllTextAsync(path);
}
}ProblemDetailsExceptionHandler converts unhandled exceptions into RFC-style problem details responses.
Register it in Program.cs:
using Superdev.AspNetCore.ExceptionHandling;
builder.Services.AddProblemDetails();
builder.Services.AddExceptionHandler<ProblemDetailsExceptionHandler>();
var app = builder.Build();
app.UseExceptionHandler();If you also want MVC/ObjectResult responses with status codes >= 400 to be normalized to ProblemDetails, add ProblemDetailsResultFilter:
using Superdev.AspNetCore.ExceptionHandling;
builder.Services.AddControllers(options =>
{
options.Filters.Add<ProblemDetailsResultFilter>();
});- Keep dependencies minimal and explicit.
- Prefer framework-native ASP.NET Core primitives over large abstraction layers.
- Move only code that is broadly reusable across multiple projects.
- Keep application-specific controllers, DTOs, mappings, secrets and business rules outside this package.
Contributors welcome! If you find a bug or you want to propose a new feature, feel free to do so by opening a new issue on github.com.