WebAPI - Returning HTTP status code without throwing or changing method signature?
-
Say I have this code:
[Route("api/authentication/change-password")] public ChangePasswordResponse Post([FromBody] ChangePasswordRequest changePasswordRequest) { using (var context = AuthenticationDBEntities.GetContext()) { var tokenResult = UserToken.ValidateToken(context, changePasswordRequest.Token, false); var user = tokenResult.User; // Ensure user is logged in if (!tokenResult.Validated) { return new ChangePasswordResponse { Success = false, ErrorCode = ChangePasswordResponseErrors.UserNotAuthenticated }; } ... snip ... return new ChangePasswordResponse { Success = true, ExpirationUTC = tokenExpires.UtcDateTime, Token = userToken.Token }; }
Obviously if the user isn't currently authenticated, I want to throw a 401 status. There are a couple ways to do that in WebAPI:
- Changing the method signature to return
IHttpActionResult
and then using the status helper functions likereturn NotAuthorized( myCustomResponseObject )
- Throwing an
HttpResponseException
, which AFAICT doesn't allow you to return any message content at all
Both these solutions suck. The first requires me to change the message signature, which is going to break stuff like automatic documentation generation. The second is one of those "use exception handling for something that's not exceptional" situations, and also doesn't let me pass my own status object (which would explain to the client, for example, why the authentication failed-- there's two ways it could fail with this change-password controller.)
Is there a better solution?
The absolutely last down-voted to shit answer to this on StackOverflow looks like it may do what I want: https://stackoverflow.com/a/45696313 except:
- It still uses exception handling to do something that's not even remotely exceptional
- It hard-codes JSON, removing the possibility of using the controller with XML (if you're going to sabotage WebAPI in that way, why even use it?)
- Changing the method signature to return
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The first requires me to change the message signature, which is going to break stuff like automatic documentation generation.
While it's still ugly to return IHttpActionResult, there is a workaround for documentation: put
[ResponseType(typeof(ChangePasswordResponse))]
as an attribute on the action method and API Explorer will use that as the response type.
-
@jbert I knew about that, but it's one of those things where you look at it and you think, "seriously? Nobody at Microsoft thought there should be an easier way to do this?"
My homegrown web API classes I wrote for a hobby project did this basic shit, and they were like maybe 1200 lines of code. It's incredible to me that the several megabytes large with hundreds of developers WebAPI doesn't.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The absolutely last down-voted to shit answer to this on StackOverflow looks like it may do what I want
I just checked, and there are no heavily downvoted answers on there. There are two answers with 1 downvote, and one answer with 2 downvotes. All three of these are heavily upvoted. The rest--the ones with low scores--just never got much attention, positive or negative.
-
@masonwheeler Great, thank you, that detailed evaluation of imaginary internetpointzzz really helps resolve my code issue.
-
@blakeyrat Perhaps not, but it does help resolve your "wild, absolutely baseless Stack Overflow bashing" issue. You claimed that the most close-to-being-useful answer got downvoted into oblivion. Not only was that not true for that answer, it's not true for any answer on the entire question.
-
@masonwheeler said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
You claimed that the most close-to-being-useful answer got downvoted into oblivion.
It's at the very bottom of the page. I don't know how their idiot internetpointzzz system works, but where I sit things at the bottom are "down".
Also I didn't use the word "oblivion". I said "to shit". Totally different.
-
@blakeyrat Sounds to me like you want to use an AuthenticationFilter. Apply the attribute to the method, and if they're not authenticated it will return the 401 for you before that method even gets invoked.
-
@unperverted-vixen said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat Sounds to me like you want to use an AuthenticationFilter. Apply the attribute to the method, and if they're not authenticated it will return the 401 for you before that method even gets invoked.
Nice tip for authentication, but doesn't help for other errors. (For example, changing password but the two new passwords don't match.)
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
I didn't use the word "oblivion". I said "to shit". Totally different.
Well of course. "I need to oblivion" makes no sense.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@unperverted-vixen said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat Sounds to me like you want to use an AuthenticationFilter. Apply the attribute to the method, and if they're not authenticated it will return the 401 for you before that method even gets invoked.
Nice tip for authentication, but doesn't help for other errors. (For example, changing password but the two new passwords don't match.)
Isn't that a bit excessive to shove that level of validation to the server?
-
@weng said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Isn't that a bit excessive to shove that level of validation to the server?
- No.
- Even if it were, how does it change my need here? That was just one of a million examples. What if the user's trying to create a Foobar with the same name as another already-existing Foobar.
-
@blakeyrat Yeah, I know. Just nitpicking that example. I personally disagree, but eh.
I also find WebAPI status returns unnecessarily cumbersome.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The first requires me to change the message signature, which is going to break stuff like automatic documentation generation.
Didn't seem to affect autodoc generation for us:
(the page on the left is generated from XMLHelp.xml, generated by the compiler itself, apparently)
'course, that depends on your doc generator using said generated file, so ymmv.
-
I have no idea whether this would work, but can you access
HttpContext.Current.Response.StatusCode
?
-
@tsaukpaetra That's because you hinted to the doc generator what the real return type is. (If you read the thread, you'll see that's actually the "solution" I'm doing now.) I was hoping not to have to do that, because it's pointless boilerplate.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
pointless boilerplate.
If you don't want pointless boilerplate, just throw an exception. 'cause that's so much bette.
Or, would you rather commandeer the system, write directly to the response stream and close it right there?
@ben_lubar said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
I have no idea whether this would work, but can you access
HttpContext.Current.Response.StatusCode
?You can, but it doesn't make a difference.
System.Web.HttpContext.Current.Response.StatusCode = 400;
Still resulted in 200 being returned.
You'd have to finish the response right then and there:
System.Web.HttpContext.Current.Response.StatusCode = 400; System.Web.HttpContext.Current.Response.Write("Fucker send me the right shit!"); System.Web.HttpContext.Current.Response.Flush(); System.Web.HttpContext.Current.Response.Close();
Sooo much less boilerplate code and much ease of use....
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
If you don't want pointless boilerplate, just throw an exception. 'cause that's so much bette.
I already said I didn't want to do that.
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Or, would you rather commandeer the system, write directly to the response stream and close it right there?
Not sure how WebAPI would react to closing its response stream, then returning from the controller method...
Eh well, I guess I have it as good as it gets, but it sucks. Sucks! It seriously shocks me that in the decades of WebAPI development, there's never been a better fix for this basic shit.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
a better fix for this basic shit.
And what would you propose as the solution?
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Not sure how WebAPI would react to closing its response stream, then returning from the controller method...
It's fine. Even if it weren't, the client wouldn't know that, so
I didn't check the logs or anything, but it didn't throw any exceptions when I tested that bodge.
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
And what would you propose as the solution?
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever; return responseObject;
It's pretty simple.
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
I didn't check the logs or anything, but it didn't throw any exceptions when I tested that bodge.
Really? Surprises me.
In any case, that goes back to "if you're going to do the serialization and construction of the HTTP protocol objects yourself, why the fuck use WebAPI in the first place?" which... seriously. My WebAPI clone was like 750 lines of code, and AFAICT was more capable.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
And what would you propose as the solution?
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever; return responseObject;
It's pretty simple.
Why would the controller instance store anything about the current response? At the very most I'd expect it to store local controller-level state information, like a db connection (though I've been told that's too).
It would be like a game engine expecting a player's Avatar to contain a reference to the bullets that are being shot at it.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever;
return responseObject;It's pretty simple.
How would that work with multi-threading, though?
I'd be ok with handling this through exceptions, BTW.
Or, if your
ChangePasswordResponse
is only used in the web layer and not a domain object, have it implementIHttpActionResult
interface. That would work, right?(with usual caveats I am rusty with this stuff, etc.)
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Why would the controller instance store anything about the current response?
Yeah yeah I can't remember how my code did it and why are you dickholes making me talk about programming on Saturday morning? It's the weekend.
EDIT: actually I do remember how I did it, I basically wrapped the actual controller in another method from the controller parent class which also handled auth and determining whether it needed to do JSONP or CORS and etc. I have the code somewhere in DropBox.
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
How would that work with multi-threading, though?
It probably wouldn't, it's fucking Saturday, I'm posting in a comedy forum, my brain is turned off, ok? Jesus. Yes I'm stupid and wrong, go away.
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Or, if your ChangePasswordResponse is only used in the web layer and not a domain object, have it implement IHttpActionResult interface. That would work, right?
I honestly didn't even think of that. It probably would, I'd have to give it a try.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
making me
You have no obligations to reply to my queries. I have no impetus against you forcing you to take action, don't play the victim on me!
-
@tsaukpaetra Oh please. You came in here, didn't read any of my posts, purely to call me an idiot for saying that changing the return type of the function breaks auto-documentation generation. Then "proved" it by posting a code sample where it works only because you used the "hey this method which returns IHttpActionResult actually returns Blah" attribute on the method. (Yeah; of course it works if you go way out of your way to add boilerplate to make it work. That wasn't what I was asking about.)
You didn't come in here in good faith; you came in here to call me an idiot not to help with my problem. I'm not "playing the victim", I am the victim of you going out of your way to be an asshole to me.
You are right, though, that I'm an idiot for replying to you when you're being an asshole, but I naively thought maybe, just maybe, you actually had some useful advice for me and it only seemed like you were being an asshole. But, no. Of course not.
At least Cartman gave me an idea to try I hadn't previously tried while he was saying I was stupid and wrong and an idiot for wanting to write code without boilerplate.
-
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever;
return responseObject;It's pretty simple.
How would that work with multi-threading, though?
WebAPI creates a new instance of your controller for each call IIRC so that shouldn't be an issue.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Throwing an HttpResponseException, which AFAICT doesn't allow you to return any message content at all
If you use the right constructor, it does. About the only real tweaking needed is making sure that the server's logging doesn't collect too much info about these exceptions, but they're absolutely a reasonable way to model telling the client “hey, you done something wrong” (which is what all 4?? HTTP response codes say).
I guess you might not do it for auth failure (that's a classic case for a filter) but other types of failure absolutely smell like exceptions.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@tsaukpaetra Oh please. You came in here, didn't read any of my posts, purely to call me an idiot for saying that changing the return type of the function breaks auto-documentation generation. Then "proved" it by posting a code sample where it works only because you used the "hey this method which returns IHttpActionResult actually returns Blah" attribute on the method. (Yeah; of course it works if you go way out of your way to add boilerplate to make it work. That wasn't what I was asking about.)
When that's exactly what the "boilerplate" is supposed to be solving, why wouldn't I post it?
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
You didn't come in here in good faith; you came in here to call me an idiot not to help with my problem. I'm not "playing the victim", I am the victim of you going out of your way to be an asshole to me.
You have not right to tell me what my intentions are. And I'm not being an asshole to you, as far as I can see. If I am, please explain, as I've clearly missed that.
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
You are right, though, that I'm an idiot for replying to you when you're being an asshole, but I naively thought maybe, just maybe, you actually had some useful advice for me and it only seemed like you were being an asshole. But, no. Of course not.
As far as I'm concerned, I did give you useful advice on how to solve the task in the easiest method possible. If doing so makes me seem to be an asshole, well that's your interpretation and I'm sorry you feel that way.
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
At least Cartman gave me an idea to try I hadn't previously tried while he was saying I was stupid and wrong and an idiot for wanting to write code without boilerplate.
I did. I showed you how to hijack the output stream and produce the desired results without throwing or changing method signature. Granted, it was after @ben_lubar's suggestion, but you can't argue that.
Also, cite exactly where I said you were "stupid and wrong and an idiot for wanting to write code without boilerplate." I dare you.
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Also, cite exactly where I said you were "stupid and wrong and an idiot for wanting to write code without boilerplate." I dare you.
OTOH, it's C# so it's not exactly 100% free of boilerplate in the first place. Maybe not as bad as Java, but that's not exactly the best choice of comparison one could make (unless the aim is to prove that one's language of choice sits at the front of the short bus).
-
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever;
return responseObject;It's pretty simple.
How would that work with multi-threading, though?
Why would it? A controller is created per request. So when you return a response, the controller is disposed of. So it’s perfectly cromulent to make it thread unsafe. I mean, it probably already is, if you’re using EF there and you’re throwing the context in.
-
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever;
return responseObject;It's pretty simple.
How would that work with multi-threading, though?
Why would it? A controller is created per request. So when you return a response, the controller is disposed of. So it’s perfectly cromulent to make it thread unsafe. I mean, it probably already is, if you’re using EF there and you’re throwing the context in.
I've never really tested it to find out. I was told in various places that having the database context at the controller level was doing it wrong because thread pools and whatever, and that instead I should instead instantiate it only at the exact point that I'm using it.
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
That the WebController parent class have a property it can use to store the HttpStatus that should go in the response once the response is created.
this.ResponseCode = HttpStatus.Whatever;
return responseObject;It's pretty simple.
How would that work with multi-threading, though?
Why would it? A controller is created per request. So when you return a response, the controller is disposed of. So it’s perfectly cromulent to make it thread unsafe. I mean, it probably already is, if you’re using EF there and you’re throwing the context in.
I've never really tested it to find out. I was told in various places that having the database context at the controller level was doing it wrong because thread pools and whatever, and that instead I should instead instantiate it only at the exact point that I'm using it.
You should wrap it into a UOW-enabled repository, but not because of the controller, but because of multi threading and the rest of that shit.
For a controller itself it doesn’t matter. A controller is instantiated per request. That’s extremely important when it comes to dealing with EF and transactions. So yeah, you could easily extend ApiController and add a status code property there, along with a ReturnResponse() method or whatever.
-
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
UOW-enabled
God. Damned.
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
you could easily extend ApiController and add a status code property there, along with a ReturnResponse() method or whatever.
I'm sure that's so much better for Blakeyrat's usability than boilerplate....
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
UOW-enabled
God. Damned.
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
you could easily extend ApiController and add a status code property there, along with a ReturnResponse() method or whatever.
I'm sure that's so much better for Blakeyrat's usability than boilerplate....
UOW = Unit Of Work
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
UOW-enabled
God. Damned.
Right. I mean unit of work. Nasty little bugger. ;)
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
you could easily extend ApiController and add a status code property there, along with a ReturnResponse() method or whatever.
I'm sure that's so much better for Blakeyrat's usability than boilerplate....
TBH, I think it is. It's a small amount of code that can be easily reused.
-
@kt_ said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
small amount of code
Sweet! So when should we expect your implementation as pulled into MS' GitHub?
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The first requires me to change the message signature, which is going to break stuff like automatic documentation generation
You can get around this problem by using the ResponseType attribute, which would make your code look like this:
[Route("api/authentication/change-password")] [ResponseType(ChangePasswordResponse)] public IHttpActionResult Post([FromBody] ChangePasswordRequest changePasswordRequest)
Using IHttpActionResult is best practice, because there are many valid scenarios where you will want to return something other than your data object. The alternative, as you rightly point out, is to use exceptions for non exceptional conditions, which does indeed suck.
I understand your desire to keep the object as part of the method signature, but keep in mind, this isn't a class library, and your expectation seems to be based on the fact that you want this to look like regular C# code. This is a Web API that happens to be implemented in C#, and you need to obey standard patterns and practices that are correct for that technology. The appropriate response type is therefore an IHttpActionResult, or a HttpResponseMessage.
Feel free to keep your objects in your method signature, but that will come at the cost of not being able to set response types easily.
-
@cartman82 said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Or, if your ChangePasswordResponse is only used in the web layer and not a domain object, have it implement IHttpActionResult interface. That would work, right?
Good idea but:
Severity Code Description Project File Line Suppression State
Error CS0535 'ChangePasswordResponse' does not implement interface member 'IHttpActionResult.ExecuteAsync(CancellationToken)'It would work, but turn my POCOs into something much more than POCOs, which is also stupidly unnecessarily boilerplate-y.
-
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
You can get around this problem by using the ResponseType attribute, which would make your code look like this:
Yes, yes, that's been mentioned about 37 times, thank you.
It's still pointless boilerplate.
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Using IHttpActionResult is best practice, because there are many valid scenarios where you will want to return something other than your data object.
... no?
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
I understand your desire to keep the object as part of the method signature, but keep in mind, this isn't a class library, and your expectation seems to be based on the fact that you want this to look like regular C# code.
What's the point of using this HUGE library blackbox bullshit dependency if it can't even shield me from the absolute simplest details of the protocol it uses? Why the fuck are my abstractions leaking, even after a decade plus of development time from Microsoft?
Demand better.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
It would work, but turn my POCOs into something much more than POCOs, which is also stupidly unnecessarily boilerplate-y.
Yeah, I figured. That's why I stipulated this is cool only if the objects you are returning are explicitly part of the API layer (in which case, you'd inherit them from some base class that implements
ExecuteAsync
).If these are actual data carriers that you are using in your business logic, then no. Better keep them POCOs.
-
using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Controllers; namespace XXX.Platform.API { public class ApiControllerWithStatus : ApiController { private bool statusSet; private HttpStatusCode status; public HttpStatusCode Status { get { return this.status; } set { this.status = value; this.statusSet = true; } } public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) { return Task.Factory.StartNew(() => { HttpResponseMessage result; result = base.ExecuteAsync(controllerContext, cancellationToken).Result; if (this.statusSet) { result.StatusCode = Status; } return result; }, cancellationToken); } } }
Feel free to post the 27 ways this code is stupid and wrong.
Seems to work though.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
You can get around this problem by using the ResponseType attribute, which would make your code look like this:
Yes, yes, that's been mentioned about 37 times, thank you.
It's still pointless boilerplate.
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Using IHttpActionResult is best practice, because there are many valid scenarios where you will want to return something other than your data object.
... no?
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
I understand your desire to keep the object as part of the method signature, but keep in mind, this isn't a class library, and your expectation seems to be based on the fact that you want this to look like regular C# code.
What's the point of using this HUGE library blackbox bullshit dependency if it can't even shield me from the absolute simplest details of the protocol it uses? Why the fuck are my abstractions leaking, even after a decade plus of development time from Microsoft?
Demand better.
It's running on HTTP. Everything webby must maximize for the priesthood of bullshit rules lawyers.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Feel free to post the 27 ways this code is stupid and wrong.
It's dealing with HTTP. Stupid and wrong comes with the territory. Still, if it's working that's a good sign (and better than a ton of other web code out there).
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
What's the point of using this HUGE library blackbox bullshit dependency if it can't even shield me from the absolute simplest details of the protocol it uses? Why the fuck are my abstractions leaking, even after a decade plus of development time from Microsoft?
It's not an abstraction. It's an implementation of a web based API. If you don't like it, choose a different technology. Perhaps WCF would suit your tastes better.
-
@doctorjones No. WebAPI is definitely an abstraction layer.
It's an abstraction layer on top of ASP.net, which is an abstraction layer on top of HTTP.
-
@weng you're missing my point. Which is probably due to poor explanation on my part.
C# is an abstraction on top of IL and that is an abstraction on top of assembler. Both facts are irrelevant to the discussion.
Blakey's gripe is that this abstraction is leaking into his C#. I'm just trying to get him to view it as the technology choice that it is. It is not plain C#, it is not an abstraction of Web API, it IS Web API.
My point is this, if you don't like Web API, don't use it. It would be your loss.
-
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
My point is this, if you don't like Web API, don't use it.
If it were a personal project, I wouldn't. I hate huge bloated dependencies that don't have enough functionality to justify themselves.
But this is a corporate project which will eventually have a team working on it, and it's a lot easier to find developers who understand WebAPI than anything else.
@doctorjones said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
It would be your loss.
I'm not sure that's true.
Seriously, in the simplest case of a controller-- one where it always returns the exact same type-- why shouldn't I be able to make the controller method just return that type?
Yes it's great that the IHttpActionResponse or whatever class lets me return a variable schema, but I'm not going to use that functionality and I'd like my simple case to look simple without the boilerplate. Require me to add the boilerplate when I need it, is all I'm asking.
I'm not sure what's so wrong about that.
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Seriously, in the simplest case of a controller-- one where it always returns the exact same type-- why shouldn't I be able to make the controller method just return that type?
But it isn't. It's returning a type with possible modification of underlying protocol. Your method shouldn't care that it happens to be in http and therefore shouldn't need to know that it wants to return HTTP 400. The moment it needs to do so is the moment you step up and use the IHttpActionResult, because that's what it's there five.
-
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
But it isn't. It's returning a type with possible modification of underlying protocol.
I'm not modifying the HTTP protocol, I have no idea what you intended to type there.
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
Your method shouldn't care that it happens to be in http and therefore shouldn't need to know that it wants to return HTTP 400.
WebAPI specifically requires HTTP. (You would be correct, however, with WCF which explicitly does not require HTTP specifically).
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The moment it needs to do so is the moment you step up and use the IHttpActionResult, because that's what it's there five.
But you always need to. There's no controller that can succeed in 100% of cases.
(Some pedantic dickweed is gonna come in here and imagine some obscure-ass controller that succeeds 100% of the time, and to that person: fuck you in advance.)
-
@blakeyrat said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
But it isn't. It's returning a type with possible modification of underlying protocol.
I'm not modifying the HTTP protocol, I have no idea what you intended to type there.
What I meant is that you're expecting mixed standards, saying "I want to program this way!" but then complaining when doing so doesn't let you do what you want.
Your choices are:
- Clean Un
decoratedboilerplate C#, in which you can't touch (and don't expect to touch) anything relating to whatever is abstracting the inputs/outputs of your class. In your OP, this would mean no[Route(
and[FromBody]
decorations, because that's ugly boilerplate after all. - Dirty ugly
decoratedboilerplate C# that lets your class be aware that it's being abstracted specifically by WebAPI, and able to take advantage of the tools and functions it offers, which lets you do WebAPI-specific things like modify the HTTP Status Code. - Something in between
- Something hacky.
@tsaukpaetra said in WebAPI - Returning HTTP status code without throwing or changing method signature?:
The moment it needs to do so is the moment you step up and use the IHttpActionResult, because that's what it's there five.
But you always need to. There's no controller that can succeed in 100% of cases.
Always need to what? Use the IHttpActionResult ? That's demonstrably false, otherwise you wouldn't be able to return anything but that in your method.
Besides, the standard way to tell C# that your method failed is to... throw an exception, which is exactly one of the things you're complaining about. Granted, throwing an exception is smelly, but that's what you'd use in a non-WebAPI function (or otherwise modify your output to provide such info, which would gasp change your method signature).
- Clean Un