How to set a Json response in suave webpart

烈酒焚心 提交于 2019-12-05 14:18:30

Looks like you've pulled in a few Json serialization libraries too many - you seem to mix bits of Json.NET and Chiron (which is used in the tutorial), to no great effect...

Let's take a step back. Suave comes with its own Json serialization module, so you can get something working just by using that. Here's how it would look:

let php =
    request (fun r ->
        match r.queryParam "playerName" with
        | Choice1Of2 name ->  
            let json : string = 
                create
                // this comes from Suave.Json, gives you a byte array
                |> Json.toJson           
                // converts the byte array into a string
                |> System.Text.Encoding.UTF8.GetString
            OK json
        | Choice2Of2 msg -> BAD_REQUEST msg)

Now, if you want, you can replace the Json.toJson call with either the Newtonsoft Json.NET or Chiron implementation (but hopefully not a mix of the two). As long as the types align, you should be fine.

For Chiron in particular, you're missing the ToJson static member on the type you want to serialize (this is something that your tutorial does mention). Json.NET has a generic serialize function that produces json corresponding to the record schema, so it's a bit easier to use out of the box, but also requires more work to customize the output if needed.

If you want to return a HTTP 200 response with JSON and set HTTP headers in Suave, then you can use the Writers.setHeader function:

Writers.setHeader "Access-Control-Allow-Credentials" "true" >=>
Writers.setHeader "Access-Control-Allow-Headers:Content-Type" "Accept" >=>
Writers.setHeader "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS" >=>
Writers.setHeader "Access-Control-Allow-Origin" "" >=>
Successful.OK (movies |> Json.serialize |> Json.format)

The whole thing is an expression that constructs a WebPart which you can then compose with other web parts using the functions provided by Suave. So if you wanted to pattern match before setting the headers, you'd use something like:

let php = request (fun r ->
  match r.queryParam "playerName" with
  | Choice1Of2 name ->  
      Writers.setHeader "Access-Control-Allow-Credentials" "true" >=>
      Writers.setHeader "Access-Control-Allow-Headers:Content-Type" "Accept" >=>
      Writers.setHeader 
        "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS" >=>
      Writers.setHeader "Access-Control-Allow-Origin" "" >=>
      Successful.OK (movies |> Json.serialize |> Json.format)
  | Choice2Of2 msg -> BAD_REQUEST msg)

As you are setting the CORS headers, this snippet might also help.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!