Reputation: 839
I have a similar question to F# syntax for async controller methods in ASP.NET Core
I'm new to F# and coming at this with a C# mindset which is obviously not serving me here.
I am creating a .Net Core controller. I have a repository that returns F# Async<seq<a>>
from ListProducts
method. Now, I want to use it in a controller action. I'm getting a 200 OK but with empty response body. Not only that, when I put breakpoints, my async seems to be executed twice? Here's a snippet:
module ActionResult =
let ofAsync (res: Async<IActionResult>) =
res |> Async.StartAsTask
[<ApiController>]
[<Route("v2/[controller]/{resource}/[action]")>]
type MyController (repository : IMyRepository) =
inherit ControllerBase()
[<HttpGet>]
member this.Products(resource: string): Task<IActionResult> =
// Debugging: if I put a breakpoint on following line it is hit once
let dummy = ""
ActionResult.ofAsync <| async {
// Debugging: breakpoint on following line hit twice?!
let! data = repository.ListProducts(resource)
// Debugging: data contains one product but response body is empty
// (not `[]`, not `[{}]`, it's a blank page)
return JsonResult(data) :> IActionResult
}
I don't know what the correct way to think about async is, yet. What is the underlying reason for having data but getting an empty response body? Is the async not done yet? How do I force it to run?
Upvotes: 0
Views: 576
Reputation: 17153
I'm not able to reproduce what you're describing. The page renders as expected for me. Here's what I did:
module ActionResult =
let ofAsync (res: Async<IActionResult>) =
res |> Async.StartAsTask
[<ApiController>]
[<Route("mypage")>]
type MyController () =
inherit ControllerBase()
[<HttpGet>]
member this.Products(): Task<IActionResult> =
ActionResult.ofAsync <| async {
let! data = async.Return(["hello"; "world"])
return JsonResult(data) :> IActionResult
}
mypage
in Edge with the following result:Upvotes: 1