Как установить ответ Json в учтивой веб-части

Я начинаю с Suave и F#. Я пытаюсь передать сериализованный объект json в мою веб-часть, чтобы получить его в своем ответе.

В PHP у меня есть это

<?php
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Headers:Content-Type, Accept');
header('Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Origin:*');
?>
{
 "player1Key":"hdegftzj25",
 "gameKey":"aegfhzkfszl74852"
}

и с этим я получаю свой объект json, затем я пытался сделать то же самое с Suave и Newtonsoft.Json

type gameCreate= {
    player1Key : string
    gameKey: string
}

let create= { player1Key = "BadBoys2"; gameKey = "zLUGgtrht4456" }

let json = Newtonsoft.Json.JsonConvert.SerializeObject(create)

//OK (acc |> Json.serialize |> Json.format )
let php =
request (fun r ->
    match r.queryParam "playerName" with
    | Choice1Of2 name ->  OK (movies |> Json.serialize(json) |> Json.format(json))
                        //|>  Response.response(Json.toJson(info))
                        //|>  OK
    | Choice2Of2 msg -> BAD_REQUEST msg)

let webPart = 
choose [
path "/" >=> (OK "Home")
path "/elm/api/create.php" >=> php
]

startWebServer defaultConfig webPart

Таким образом, я могу создать и сериализовать объект json, но я не знаю, как передать его как http-ответ в моей веб-части, и с помощью приведенного выше кода я продолжаю получать сообщение об ошибке в моем типе выражений в моем let php

2 ответа

Решение

Похоже, вы использовали слишком много библиотек сериализации Json - кажется, вы смешиваете биты Json.NET и Chiron (которые используются в руководстве) без особого эффекта...

Давайте сделаем шаг назад. Suave поставляется с собственным модулем сериализации Json, так что вы можете получить что-то работающее, просто используя это. Вот как это будет выглядеть:

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)

Теперь, если вы хотите, вы можете заменить Json.toJson вызовите либо с реализацией Newtonsoft Json.NET, либо с Chiron (но, надеюсь, не сочетанием этих двух). Пока типы совпадают, у вас все будет хорошо.

В частности, для Хирона вам не хватает ToJson статический член типа, который вы хотите сериализовать (это то, что упоминается в вашем руководстве). Json.NET имеет универсальную функцию сериализации, которая генерирует json, соответствующий схеме записи, так что это немного проще в использовании, но также требует больше работы для настройки вывода при необходимости.

Если вы хотите вернуть ответ HTTP 200 с JSON и установить заголовки HTTP в Suave, то вы можете использовать Writers.setHeader функция:

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)

Все это выражение, которое создает WebPart которые вы затем можете создавать с другими веб-частями, используя функции, предоставляемые Suave. Поэтому, если вы хотите сопоставить шаблон перед установкой заголовков, вы должны использовать что-то вроде:

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)

Когда вы устанавливаете заголовки CORS, этот фрагмент может также помочь.

Другие вопросы по тегам