It is possible and not ideal to do this: (a vastly simplified example!)
[Serializable]
public class MyRecord
{
public string key {get; set;}
public string data {get; set;}
}
public async Task<IHttpActionResult> Get(string SomeKey)
{
if(ExistsInDB(SomeKey))
{
return Ok(SomeRecordFromDB(SomeKey)); //SomeRecord() returns a POCO MyRecord.
}
else
{
//I know I can return NotFound() but not the focus of my Q
return Ok(false); //returns "False"
}
}
Effectively demonstrating no compile time error checking on the return type. This example will return either a JSon serialized POCO class (JSon is set on my accept header) or it will return the text "False" which puts the burden of type checking on the client.
I wouldn't do this by design but my team is refactoring a lot of code from asmx/svc and mistakes creep in. I like it when the compiler helps to trap these kinds of errors rather than waiting for module or unit testing.
Is the right way to go back to using strongly typed method signatures (avoiding the IHttpActionResult and the Ok(), NotFound(), etc helpers or is there something like a IHttpActionResult<T>
that can be used to make sure the right type is being returned?
M.
The problem with using strongly typed method signatures is that there is no way for you to return an "error" object if something is wrong with the request, be it validation errors or not found errors.
So if you want to use strongly typed signatures then you either have to included some sort of "error" object reference in your return type or explicitly throw exceptions..
The good thing about using HttpActionResult is that you are not constrained to a specific return type. So you could, for example, return OK(someObject) or BadRequest(errorObject). However, it is up to the developer to write the method correctly and double check that nothing happens like the example you mentioned above.
You can refactor your code this way:
First of all, it is a good practice to return
IHttpActionResult
, indicating the correspondinghttp status
. Something like:But if you really want to have a strongly typed api, you can do something like:
Or, create a typed response, and you'll keep the http status code, etc in your response:
And then you can create your method:
Creating your own custom generic IHttpActionResult
It's basically the same:
And now you can return the class you want with a typed
IHttpActionResult
: