C
C#4mo ago
S-IERRA

ASP.Net IActionResult always returns Ok

I have the following method inside of a service, I call this method from a controller Where its suppsoe to return 404 not found it enters the return statement and jumps to the last line of the method (Return Ok) This seems to happen on all methods, possibly there is a better way of returning values from services?
public async Task<IActionResult> DeleteServer(int id)
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();

if (await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id) is not { } server)
return new NotFoundObjectResult(new ErrorResponse(RestErrors.FailedToFind($"server{id}")));

dbContext.Servers.Remove(server);
await dbContext.SaveChangesAsync();

return new OkResult();
}
public async Task<IActionResult> DeleteServer(int id)
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();

if (await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id) is not { } server)
return new NotFoundObjectResult(new ErrorResponse(RestErrors.FailedToFind($"server{id}")));

dbContext.Servers.Remove(server);
await dbContext.SaveChangesAsync();

return new OkResult();
}
This is how I call this method
[HttpDelete("{id:int}/delete")]
public async Task<IActionResult> DeleteServer(int id)
{
return await _serverService.DeleteServer(id);
}
[HttpDelete("{id:int}/delete")]
public async Task<IActionResult> DeleteServer(int id)
{
return await _serverService.DeleteServer(id);
}
40 Replies
Waffles from Human Resources
Are you sure the condition is even being called? You should print out your condition and set a print statement into the error result so you know the state of the condition and if it's being called
S-IERRA
S-IERRA4mo ago
The condition is being called, its not that, it enters the return statement then the return statement makes it jump to the bottom fo the method making it reutrn 200 instead of 404
Waffles from Human Resources
return NotFoundResult instead of NotFoundObjectResult maybe that works
Angius
Angius4mo ago
It probably "enters" the if because it needs to execute the db call and get the server, meaning it exists I'd extract the condition to a separate variable, just to see what happens And to be able to place a breakpoint on it to see what it actually is (also, why DbContextFactory...?)
S-IERRA
S-IERRA4mo ago
To keep a seperate context no? altough I assume DI would take care of that, also, thats not whaat I meant, what I meant is it will enter the if and it should return 404 but instead it jumps to the bottom of the code It is something that literally makes 0 sense logically
S-IERRA
S-IERRA4mo ago
No description
S-IERRA
S-IERRA4mo ago
that return makes it jump there
Angius
Angius4mo ago
Just inject the context, save yourself the trouble
S-IERRA
S-IERRA4mo ago
instead of actually returning from the method
Angius
Angius4mo ago
Huh Yeah, that does make no sense
S-IERRA
S-IERRA4mo ago
Yeah
Angius
Angius4mo ago
I'd still try to extract the condition and see what it is
S-IERRA
S-IERRA4mo ago
been trying not to smash my head against a wall Nah the condition is fine, its cant find the id like its suppose to fail there cuz im feeding it false data but it should return 404 this happens on every method Mind you this could be something to do with the fact that this method isnt in a controller but in service
Angius
Angius4mo ago
I just wonder whether it's await (FindFirst is not {} server) or (await FindFirst) is not {} server that happens Because FindFirstAsync would always return a Task, which would mean it technically never matches the condition
S-IERRA
S-IERRA4mo ago
async concurrency issue possibly
Angius
Angius4mo ago
Unlikely, you're not doing any super complex code here More likely that it's pattern matching on a task, not on its result
S-IERRA
S-IERRA4mo ago
hmm wdym by that actually let me convert it to a normal if then @ZZZZZZZZZZZZZZZZZZZZZZZZZ You mind if i dm you a vid of this happening? cuz it has a bunch of data thats relativly sensitive and its hard for me to show you exactly what is happening without a vid
Angius
Angius4mo ago
What I mean, is
await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id) is not { } server
await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id) is not { } server
might be treated as
var task = dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
task is not { } server;
await server;
var task = dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
task is not { } server;
await server;
and not
var result = await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
result is not { } server;
var result = await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
result is not { } server;
S-IERRA
S-IERRA4mo ago
yes but the return statement still shouldnt skip to the bottom
Angius
Angius4mo ago
Let's remove anything that could possibly be an issue first, aight?
S-IERRA
S-IERRA4mo ago
btw
Angius
Angius4mo ago
public async Task<IActionResult> DeleteServer(int id)
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();

var thing = await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
if (thing is not { } server)
{
return new NotFoundObjectResult(new ErrorResponse(RestErrors.FailedToFind($"server{id}")));
}

dbContext.Servers.Remove(server);
await dbContext.SaveChangesAsync();

return new OkResult();
}
public async Task<IActionResult> DeleteServer(int id)
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();

var thing = await dbContext.Servers.FirstOrDefaultAsync(x => x.Id == id);
if (thing is not { } server)
{
return new NotFoundObjectResult(new ErrorResponse(RestErrors.FailedToFind($"server{id}")));
}

dbContext.Servers.Remove(server);
await dbContext.SaveChangesAsync();

return new OkResult();
}
I guess I can open my DMs briefly
S-IERRA
S-IERRA4mo ago
alright 1m then
Angius
Angius4mo ago
There
S-IERRA
S-IERRA4mo ago
just fyi the src looks a bit diff to what i sent in-order to protect privacy but yeah 1s just var name changes if yw close them i ll let you know when im gonna send gotta record it rq I think i understand why fucking hell The method that calls this was a sync method and this is async, I also didnt return the value of this call properly just returned Ok so I assume what happened is because this is async it skipped over it and returned Ok which is why it did this
Angius
Angius4mo ago
Ah, well, async over sync will do that to you lmao
S-IERRA
S-IERRA4mo ago
still weird as hell to see that
Angius
Angius4mo ago
Yeah, if something's async but unawaited, the execution will just skip over it I take it I can close my DMs now?
S-IERRA
S-IERRA4mo ago
Yes sure Yeah that seemed to be the issue, weird as hell but yeah still thanks for the help
Angius
Angius4mo ago
I wonder if there's some "unawaited task" analyzer
S-IERRA
S-IERRA4mo ago
debugger at most ig but its hard to do that because at the same time, it has to intended design there is _ = asyncMethod() to ignore other wise it screams with a warning but thats about it
Angius
Angius4mo ago
Yeah Never wrote a Roslyn analyzer, but I might add this to my growing list of future projects lol
S-IERRA
S-IERRA4mo ago
Sounds quite cool id be interested to join you on that down the line Never worked too much with compilers tho
Angius
Angius4mo ago
Generators and analyzers aren't the most ergonomic to write, but they're not that bad I can recommend it for a weekend project
S-IERRA
S-IERRA4mo ago
worked a bit with src gens via attributes wanted to blow my brains out I wanted to create a macro language similar to rusts its funny because its very possible in c# just nobody has done it i.e
[Macro("r(5, print(\"Hello World!\"))")]
public void MethodName();
[Macro("r(5, print(\"Hello World!\"))")]
public void MethodName();
then have a src gen generate a for loop to repeat a print 5 times just its annoying as hell, writing a macro to c# transpiler
Angius
Angius4mo ago
Sounds like a job for interceptors
S-IERRA
S-IERRA4mo ago
then dealing with src gen
Angius
Angius4mo ago
But yeah, this would basically require an entire DSL embedded in the generator lol
S-IERRA
S-IERRA4mo ago
altough rust managed to do it surprised no one bothered in c#
Waffles from Human Resources
:SCcrying: