MSCrud.Core
0.4.1
dotnet add package MSCrud.Core --version 0.4.1
NuGet\Install-Package MSCrud.Core -Version 0.4.1
<PackageReference Include="MSCrud.Core" Version="0.4.1" />
<PackageVersion Include="MSCrud.Core" Version="0.4.1" />
<PackageReference Include="MSCrud.Core" />
paket add MSCrud.Core --version 0.4.1
#r "nuget: MSCrud.Core, 0.4.1"
#:package MSCrud.Core@0.4.1
#addin nuget:?package=MSCrud.Core&version=0.4.1
#tool nuget:?package=MSCrud.Core&version=0.4.1
MSCrud
Generic CRUD stack for ASP.NET Core + EF Core. Register an entity once and get a full
REST endpoint (GetAll, GetById, Create, Update, Delete, Search, Find) with
pagination, validation, optional caching and audit support — no per-entity controller,
service or repository code required.
| Package | Contents |
|---|---|
MSCrud.Abstractions |
Contracts: ICrudRepository, ICrudService, ICrudMapper, ICacheProvider, ILocalizationProvider, [Searchable]/[Filterable] attributes and response types. |
MSCrud.Core |
EF Core implementation: CrudRepository, CrudService, CachingCrudServiceDecorator, PaginatedService, AuditSaveChangesInterceptor. |
MSCrud.Web |
ASP.NET Core integration: generic CrudController, dynamic controller registration and the AddCrud/AddCrudEntity DI extensions. |
Quickstart
builder.Services.AddControllers()
.AddCrud(o => { o.CachingEnabled = true; o.RoutePrefix = "/api/v1"; })
.AddCrudEntity<Example, ExampleDTO, ExampleAttributesDTO, int>(o => o.WithMapper<ExampleMapper>());
// MSCrud resolves a plain DbContext; forward it to your concrete context.
builder.Services.AddScoped<DbContext>(sp => sp.GetRequiredService<BaseProjectContext>());
This exposes Example at /api/v1/Example with the standard CRUD + Search/Find actions.
Requirements per entity
- The entity implements
IEntityId<TKey>(and optionallyIAuditableEntityfor audit columns). - An
ICrudMapper<TEntity, TDto, TAttributesDto>implementation, registered viao.WithMapper<ExampleMapper>(). - A FluentValidation
IValidator<TDto>with"Insert"and"Update"rule sets (used by the generic controller). - Application-wide implementations of
ILocalizationProviderand, when caching is enabled,ICacheProviderregistered in DI. Your provider must resolve the response message keys the stack uses internally (e.g."Entity created","Entity not found","Entity already exists","Entity could not be saved") — seeCHANGELOG.mdfor keys added by version.
Customization
AddCrudEntity accepts per-entity overrides:
.AddCrudEntity<Example, ExampleDTO, ExampleAttributesDTO, int>(o => o
.WithMapper<ExampleMapper>()
.WithRepository<ExampleRepository>() // subclass CrudRepository to add Includes/ordering
.WithService<ExampleService>() // replace the default CrudService
.DisableCaching() // or .EnableCaching() to override the global default
.DisableSoftDeleteCascade()) // or .EnableSoftDeleteCascade() to override the global default
AddCrud options (CrudOptions): DefaultPageSize (10), MaxPageSize (100),
MinSearchLength (3), CachingEnabled (true), RoutePrefix (/api/v1), ReadBackAfterWrite
(true) — set it to false to skip the post-save re-read on Create/Update when the
response only needs the tracked entity's scalar values (no eager-loaded navigations or
database-computed columns) — and SoftDeleteCascade (true). See CHANGELOG.md for what's new
in each release.
Soft-delete cascade
Deleting an auditable entity recursively soft-deletes its active FK children (e.g. deleting a
User soft-deletes its UserGroup join rows; Group rows are untouched). Controlled globally by
CrudOptions.SoftDeleteCascade (default true) and per entity via
EnableSoftDeleteCascade()/DisableSoftDeleteCascade(). When resolved to disabled for an entity
with active children, Delete fails with the "Entity has child dependencies" message (restrict).
Non-auditable children are never touched (a remove would hard-delete them). Child discovery
ignores HasQueryFilters (0.4.1): tenant/visibility filters cannot hide children from the
restrict check or the cascade — only the walk's own !IsDeleted predicate excludes rows. See
CHANGELOG.md 0.4.0 for the full contract.
Search and filtering
Mark
stringproperties with[Searchable]to include them inGET /Search?search=(SQLLIKE).Mark FK/value-type properties with
[Filterable]for exact-match filtering throughPOST /Find(query-by-example).To filter one column by multiple values (SQL
IN), add a companion collection property marked[FilterableIn(nameof(TargetProp))]to the entity and the DTO, and copy it in the mapper'sToEntity. On EF entities the property must also carry[NotMapped](EF would otherwise map a bareList<int>as a primitive collection column):public class Order : IEntityId<int> { [Filterable] public int OrderStatusId { get; set; } [NotMapped] [FilterableIn(nameof(OrderStatusId))] public List<int>? OrderStatusIds { get; set; } } // POST /Order/Find {"orderStatusIds":[1,2,3]} → WHERE OrderStatusId IN (1,2,3)A
nullor empty collection means "not filtering" (same query-by-example gate as scalar properties). When both the scalar and the collection are set, the conditions are AND-chained. Misconfigured attributes (missing target property, element-type mismatch, attribute on a non-collection property) throwInvalidOperationExceptionon the firstFind/count query.
| Product | Versions 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.9)
- MSCrud.Abstractions (>= 0.4.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on MSCrud.Core:
| Package | Downloads |
|---|---|
|
MSCrud.Web
ASP.NET Core integration for MSCrud: generic CRUD controller, dynamic controller registration and AddCrud/AddCrudEntity DI extensions. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.1 | 280 | 8/2/2026 |