C
C#2mo ago
qqdev

ASP.NET: Elegant controller <-> service interaction

Hey! I am looking for an elegant controller <-> service interaction. Example (pseudocode):
[ApiController]
[Route("[controller]")]
public class CarController(ICarService carService) : ControllerBase
{
public async Task<IActionResult> UpdateCar(CarDto carDto)
{
var (car, statusCode) = await carService.UpdateCar(carDto);

if (statusCode != HttpStatusCode.OK)
{
return StatusCode((int)statusCode);
}

return Ok(car);
}
}
[ApiController]
[Route("[controller]")]
public class CarController(ICarService carService) : ControllerBase
{
public async Task<IActionResult> UpdateCar(CarDto carDto)
{
var (car, statusCode) = await carService.UpdateCar(carDto);

if (statusCode != HttpStatusCode.OK)
{
return StatusCode((int)statusCode);
}

return Ok(car);
}
}
My issue with this code: The service layer is returning an HTTP status code although the car service shouldn't have to do anything with HTTP stuff. I thought about adding a dedicated enum which would kinda imitate some of the HTTP status codes (OK, NotFound, Conflict). Other ideas: - Throw custom exceptions (don't like this one, exceptions are ugly) Do you have a more convenient solution for this issue? How do you deal with this kind of stuff? Thanks in advance! Related: - https://stackoverflow.com/questions/76990166/what-should-the-service-layer-return-to-the-controller-when-validating-data-in-s - https://www.reddit.com/r/dotnet/comments/yyix35/mvc_how_do_you_return_failures_from_services/
7 Replies
Keswiik
Keswiik2mo ago
At work we'd normally use exceptions for this type of flow control, but my day job is java and our services aren't implemented within the API itself (all messaging through a broker such as rabbitmq). I don't see any harm returning an internal enum that you can map to HTTP statuses.
Pobiega
Pobiega2mo ago
If the errors are meaningfully different, I would probably go with a result type (there is a tag with a bunch of result type libs) Might also want to look at something like Immediate.Handlers
kurumi
kurumi2mo ago
I usually return Result<T>, so I can set it success or failer with error message
qqdev
qqdev2mo ago
Thanks! I will probably return a tuple because it’s not always an "either a or b" scenario. Example: Was the entity created or updated? I could also return a Result<(Entity, CreatedOrUpdatedEnum> in that case I guess
Pobiega
Pobiega2mo ago
might be a good usecase for OneOf where you could return either a EntityUpdatedResult, EntityCreatedResult or one of a list of errors a bit unergonomic to deal with in C# imho, since there just isnt language support for DUs
qqdev
qqdev2mo ago
Yeah that’s what’s holding me kinda back Rust, for example, is build around Results/Options and it’s so ergonomic
Pobiega
Pobiega2mo ago
yeah Result<T> can be fairly ergonomic, with as singular return and if you dont need exhaustive error matching but full blown OneOf is nuts
Want results from more Discord servers?
Add your server
More Posts
Can't figure out how to apply attributes to values in json property dictionary (System.Text.Json)This is my model that I'm working with ```csharp //TODO convert to DateTime [JsonPropertyName("peacRecommendation for handling logging in a APIHello Hello. Im fairly new in the DOTNET world so im not familiar with all the libs. I want to use Reading config files (mostly secrets) from outside appsettings and env vars - bad idea?Looking for best practices / existing features to avoid reinventing the wheel (more than we have). asp - Calling another api endpointHey, i have a stream containing a raw request and would like to call the asp.net core request pipeliTesting practices and librariesI'm just starting with testing, I'm not that much of a fan, most of the time for me it wasn't neededSwitching to C# and curious if there's anything I could improve on in this very basic math script.```c# class Program { static void Main() { MathClass.Print(2,5,"subtract"); } } General Google SSO Login QuestionSo i've set up my Google SSO in ASP.NET; And when logging in you get returned a JWT Token. Our FroHow to write Testcases with ServiceProvider.GetKeyedService method in .Net 8?**DI Registeration** ` services.AddKeyedTransient<IReceivableDocument,BuyerReceivableDocumentStrateIdentity problemI have scaffolded Identity pages for user authorization and authentication and i have a problem. theBlazor validation - validation message not added?Hi, i have created a base form component and I use another Blazor form component. The issue is tha