EntityModelBinder 1.0.2
dotnet add package EntityModelBinder --version 1.0.2
NuGet\Install-Package EntityModelBinder -Version 1.0.2
<PackageReference Include="EntityModelBinder" Version="1.0.2" />
<PackageVersion Include="EntityModelBinder" Version="1.0.2" />
<PackageReference Include="EntityModelBinder" />
paket add EntityModelBinder --version 1.0.2
#r "nuget: EntityModelBinder, 1.0.2"
#:package EntityModelBinder@1.0.2
#addin nuget:?package=EntityModelBinder&version=1.0.2
#tool nuget:?package=EntityModelBinder&version=1.0.2
Route Entity Model Binder 🚀
A Laravel-inspired Route Model Binder for ASP.NET Core. Automatically resolves database entities from route parameters, eliminating repetitive lookup code and streamlining your API controllers.
Why EntityModelBinder?
In RESTful APIs, you often need to fetch database entities based on route parameters. Instead of writing repetitive lookup code in every endpoint, EntityModelBinder automatically resolves the entity for you—exactly like Laravel's route-model binding.
Installation
dotnet add package EntityModelBinder
Quick Start
1. Implement IEntity on your database model
using EntityModelBinder;
public class Product : IEntity
{
public int Id { get; set; }
public string Slug { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
2. Register the service in your Program.cs
builder.Services.AddEntityModelBinder<SomePostgresContext>(options =>
{
options.EnableSwaggerSchemaIds = true;
options.SuppressModelStateInvalidFilter = true;
});
3. Use in your API controllers
[HttpGet("products/{product}")]
public IActionResult Get([FromRoute] Product product)
{
if (product == null) return NotFound();
return Ok(product);
}
That's it! The model is automatically fetched from the database. ✌️
Advanced Usage
Using Custom Column Keys with [EntityKey]
By default, the binder searches by Id. Use the [EntityKey] attribute to bind by any column:
[HttpGet("products/{product}")]
public IActionResult Get([FromRoute, EntityKey("Slug")] Product product)
{
if (product == null) return NotFound();
return Ok(product);
}
Supported types: int, Guid, string (slugs).
Real-World Example
Before (without EntityModelBinder):
[HttpGet("{surveyId:int}")]
public async Task<IActionResult> Show([FromRoute] int surveyId)
{
var survey = await _dbContext.Survey.FindAsync(surveyId);
return Ok(survey);
}
[HttpPatch("{surveyId:int}")]
public async Task<IActionResult> Update([FromRoute] int surveyId, [FromBody] SurveyRequest request)
{
var survey = await _dbContext.Survey.FindAsync(surveyId);
survey.Name = request.name;
survey.Json = request.jsonData;
survey.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync();
return Ok(new { id = survey.Id });
}
After (with EntityModelBinder):
[HttpGet("{survey}")]
public IActionResult Show([FromRoute] Survey survey)
{
if (survey == null) return NotFound();
return Ok(survey);
}
or in some cases
[HttpGet("{survey}")]
public IActionResult Show([FromRoute] Survey survey)
=> Ok(survey);
Adding a new resource
[HttpPost]
public async Task<IActionResult> Store([FromBody] SurveyRequest request)
{
var entity = new Survey
{
Name = request.name,
Json = request.jsonData,
StructureId = _identityProvider.CurrentStructureId,
CreatedAt = DateTime.UtcNow
};
_dbContext.Surveys.Add(entity);
await _dbContext.SaveChangesAsync();
return CreatedAtAction(nameof(Show), new { survey = entity.Id }, entity);
}
[HttpPatch("{survey}")]
public async Task<IActionResult> Update([FromRoute] Survey survey, [FromBody] SurveyRequest request)
{
if (survey == null) return NotFound();
survey.Name = request.name;
survey.Json = request.jsonData;
survey.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync();
return Ok(survey);
}
Configuration
Swagger Support
If you're using Swagger/OpenAPI and encounter schema conflicts, enable the option:
builder.Services.AddEntityModelBinder(options =>
{
options.EnableSwaggerSchemaIds = true;
});
Then in your Swagger configuration:
c.CustomSchemaIds(type => type.ToString());
How It Works
- When a request hits a route like
/products/my-product-slug, the binder intercepts the parameter - It checks for
[EntityKey("ColumnName")]on the action parameter - If found, uses that column; otherwise defaults to
Id - Determines the column type (
int,Guid, orstring) - Queries the database using Entity Framework Core
- Returns the entity directly to your controller method
- Returns
404 Not Foundif the entity doesn't exist
Requirements
- .NET 8.0+
- ASP.NET Core
- Entity Framework Core 8.0+
License
MIT License - see LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- Microsoft.EntityFrameworkCore (>= 8.0.0)
-
net8.0
- Microsoft.EntityFrameworkCore (>= 8.0.0)
-
net9.0
- Microsoft.EntityFrameworkCore (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.