🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 10 Min Lesezeit
0

How To Be More Productive When Creating CRUD APIs in .NET

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

I have been creating .NET webapps for more than 10 years. I have created a lot of complex applications and a lot of CRUD APIs.

CRUD APIs by their nature are straightforward, but in every project you need to write the same boilerplate code to create, update, delete and read entities from the database.



A few years ago, I was looking for ready free solutions that will allow me to ship CRUD APIs faster. And I couldn't find the perfect solution.

So I created my own.



In today's blog post, I will show you tools that allowed me to be more productive when creating CRUD APIs in .NET.

I will show you examples of how to use these tools in an N-Tier (Layered) and Vertical Slice Architecture.




On my website: to become a better developer.

for fast and efficient development of CRUD APIs in .NET.

Have a look at the documentation on the



Within a few minutes, we have created a fully functional CRUD API for Ticket entity that has the following endpoints:




  • Get entity by id

  • get all entities

  • create entity

  • update entity

  • partial entity update

  • delete entity

  • create many entities

  • update many entities

  • delete many entities






Source generation for WebApi models in Modern Libraries



You're not limited to only using DTO models.

You can also use DBO models and expose them from the APIs, in case you need such an option:




CODE
options.AddService<Ticket, Ticket, int>();
options.AddController<CreateTicketRequest, UpdateTicketRequest, Ticket, Ticket, int>("api/tickets");






I have created a Nuget package with source generators for WebApi models:




CODE
dotnet add package Modern.Controllers.SourceGenerators






You can add this attribute to the public contract model, and the source generator will create a CreateTicketRequest and UpdateTicketRequest models:




CODE
[WebApiEntityRequest(CreateRequestName = "CreateTicketRequest",
UpdateRequestName = "UpdateTicketRequest")]
public record TicketDto
{
[IgnoreCreateRequest]
public required int Id { get; init; }
public required string Number { get; init; }
public required string Description { get; init; }
public required string Status { get; init; }
public required decimal Price { get; init; }
}






Source generator uses all the properties for Create and Update requests.

You can additionally specify what properties should be excluded from the requests by using the IgnoreCreateRequest or IgnoreUpdateRequest.





Customizing Repositories, Services and Controllers



At its core, Modern libraries follow the classic N-Tier (Layered) approach:




  • Repository

  • Service

  • Controller



Each layer can be overridden and further extended.



Modern Repository supports the following operations.



Modern Repository has Where method that you can use to filter data by a given condition.

However, you may need to create your own methods.



You can create your own repository interface that inherits from IModernRepository<TEntity, TId>.

And create an implementation that inherits from ModernEfCoreRepository<TDbContext, TEntity, TId>.



Here is an example:




CODE
public interface ICustomTicketRepository: IModernRepository<Ticket, int>
{
Task<List<Ticket>> GetTicketsByDateAsync(DateTime date);
}

public class CustomTicketRepository
: ModernEfCoreRepository<EfCoreDbContext, Ticket, int>, ICustomTicketRepository
{
public CustomTicketRepository(
EfCoreDbContext dbContext,
IOptions<EfCoreRepositoryConfiguration> configuration)
: base(dbContext, configuration)
{
}

public async Task<List<Ticket>> GetTicketsByDateAsync(DateTime date)
{
return await DbContext.Tickets
.Where(x => x.PurchasedAtUtc >= date)
.ToListAsync();
}
}






In the same manner you can create your own service interface that inherits from IModernService<TEntityDto, TEntityDbo, TId>.

And create an implementation that inherits from ModernService<TEntityDto, TEntityDbo, TId>.




CODE
public interface ICustomTicketService : IModernService<TicketDto, Ticket, int>
{
Task<List<Ticket>> GetTicketsByDateAsync(DateTime date);
}

public class CustomTicketService : ModernService<TicketDto, Ticket, int>, ICustomTicketService
{
private readonly ICustomTicketRepository _repository;

public CustomTicketService(
ICustomTicketRepository repository,
ILogger<CustomTicketService> logger)
: base(repository, logger)
{
_repository = repository;
}

public async Task<List<Ticket>> GetTicketsByDateAsync(DateTime date)
{
return await _repository.GetTicketsByDateAsync(date);
}
}






The same goes with Controllers, you can create a custom Controller that inherits from ModernController<TCreateRequest, TUpdateRequest, TEntityDto, TEntityDbo, TId>:




CODE
public record GetTicketsByDateRequest(DateTime Date);

[ApiController]
[Route("/api/custom-tickets")]
public class CustomTicketController
: ModernController<CreateTicketRequest, UpdateTicketRequest, TicketDto, Ticket, int>
{
private readonly ICustomTicketService _service;

public CustomTicketController(ICustomTicketService service) : base(service)
{
_service = service;
}

[HttpGet("get-by-date")]
public async Task<IActionResult> GetTicketsByDate(
[Required, FromBody] GetTicketsByDateRequest request)
{
var entities = await _service.GetTicketsByDateAsync(request.Date).ConfigureAwait(false);
return Ok(entities);
}
}






After creating your own implementations, you need to register them as Concrete implementations:




CODE
builder.Services
.AddModern()
.AddRepositoriesEfCore(options =>
{
options.AddRepository<EfCoreDbContext, Ticket, int>();
options.AddConcreteRepository<ICustomTicketRepository, CustomTicketRepository>();
})
.AddServices(options =>
{
options.AddService<TicketDto, Ticket, int>();
options.AddConcreteService<ICustomTicketService, CustomTicketService>();
})
.AddControllers(options =>
{
options.AddController<CreateTicketRequest, UpdateTicketRequest, TicketDto, Ticket, int>("api/tickets");
options.AddController<CustomTicketController>();
});






In all previous examples, we were using our own customized implementations of a Repository and Service.

What if you don't need to create your own version of Repository or Service and use just a base version from the package?



The first option is to use the base interface of IModernService or IModernRepository from the Modern package:




CODE
// Use IModernService<...> instead of ICustomTicketService
IModernService<TicketDto, Ticket, int> service

// Use IModernRepository<...> instead of ICustomTicketRepository
IModernRepository<Ticket, int> repository






If you dislike such long types, you can create your own interface and implementation that inherit from the base types and make them empty.

But this can be tedious.



If this is the case, you can use the following packages with source generators:




CODE
dotnet add package Modern.Repositories.EFCore.SourceGenerators
dotnet add package Modern.Services.DataStore.SourceGenerators






You can need to use a marker empty class and specify the ModernEfCoreRepository attribute:




CODE
[ModernEfCoreRepository(typeof(EfCoreDbContext), typeof(Ticket), typeof(int))]
public class IServiceMarker;






To autogenerate service, you need to add a ModernService attribute to the Dto class:




CODE
[ModernService(typeof(Ticket))]
public class TicketDto
{
}






NOTE: source generator only supports classes for Dto at the moment.



As a result, source generators will create the following classes:



or even combination of Vertical Slices and and the documentation on the I share .NET and Architecture best practices.

the source code for this blog post for free.


Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How To Be More Productive When Creating CRUD APIs in .NET

Thematisch verwandte Begriffe: More, Productive, When, Creating · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...