Diana
Diana

Reputation: 839

F# .Net Core controller returns 200 OK but empty response body

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

Answers (1)

Brian Berns
Brian Berns

Reputation: 17153

I'm not able to reproduce what you're describing. The page renders as expected for me. Here's what I did:

  1. Created an ASP.NET Core Web App in VS2022.
  2. Pasted the following code:
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
        }
  1. Started the app and successfully navigated to mypage in Edge with the following result:

enter image description here

Upvotes: 1

Related Questions