I'm writing an API with .NET Core 3.1. This API has an asynchronous function called GetSomeProperty()
, which I use in an endpoint (called Get
).
When receiving the response from this endpoint, the results
properties are "moved down" one layer, and wrapped in metadata from the asynchronous method, like this:
"results": [
{
"result": {//actual result here}
"id": 1,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"creationOptions": 0,
"isFaulted": false
},
{
"result": {//actual result here}
"id": 2,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"creationOptions": 0,
"isFaulted": false
}
]
I don't want these results to be wrapped in this "asynchronous" wrapper.
While keeping the method asynchronous, how can I return the task result, instead of an object containing the task result?
There are two reasons why I haven't used .Result
:
- Using
.Result
is considered bad practice, as it can cause locks if the task hasn't yet completed. - I couldn't figure out where to put it. It doesn't seem to fit anywhere, as far as I can tell.
Here is the code (please bear in mind this has been significantly diluted and simplified for example purposes):
[HttpGet]
public async Task<object> Get(string someParameter)
{
//Do stuff
var things = BuildACollectionOfItems();
var results = things.Select(x => x.IrrelevantThing).OrderBy(x => x.SomethingIrrelevant).Select(async x =>
{
return new
{
x.Id,
SomeProperty = await GetSomeProperty(x.Id)
};
}).ToArray();
return new
{
Results = ((IEnumerable<object>) results),
SomeIrrelevantThing = someIrrelevantThing
};
}
private async Task<bool> GetSomeProperty(int id)
{
var somethingFromAServer = (await _thingProvider.GetThing()).TheProperty;
//Do stuff here
var thing = _context.Stuff.FirstOrDefault(x => x.Thing == somethingFromAServer);
//Do some more stuff
return thing.Stuff;
}