如何在 F# Saturn Framework 中获取查询参数?
How to get a query parameter in F# Saturn Framework?
假设我们有这个网络服务器来处理请求:
let webApp = scope {
get "/api/zoo/animals/" (getAllAnimals())
getf "/api/zoo/animals/%s" getAnimalInfo
}
此语法在 docs and demoed in the example 中有描述。
现在,如果我想在 url 查询中包含一个参数,例如过滤结果?
http://localhost:8080/api/zoo/animals?type=mammals
这没有做任何事情:
getf "/api/zoo/animals?type=%s" getAnimalsByType
一种方法是使用上下文的函数 GetQueryStringValue
。它returnsResult,一个结构体DU.
因此您保留初始签名(只需删除结尾的斜杠):
get "/api/zoo/animals" (getAnimals())
你有
let getAnimals() : HttpHandler =
fun _ ctx -> task {
let animalTypeFromQuery = ctx.GetQueryStringValue "type"
let animalType =
match animalTypeFromQuery with
| Ok t -> Some t
| Error _ -> None
...
}
我不知道这是否是官方的做法,我在一些 F# github repos 中找到了这种做法。
查看示例:
https://github.com/giraffe-fsharp/Giraffe/blob/master/DOCUMENTATION.md#query-strings
它展示了如何绑定查询字符串中的数据,这样您就不必使用 GetQueryStringValue
在你的情况下,我认为这样的事情可能会奏效。
[<CLIMutable>]
type AnimalType =
{ type : string }
let animal (next : HttpFunc) (ctx : HttpContext) =
// Binds the query string to a Car object
let animal = ctx.BindQueryString<AnimalType>()
// Sends the object back to the client
Successful.OK animal next ctx
let web_app =
router {
pipe_through (pipeline { set_header "x-pipeline-type" "Api" })
post "/api/animal" animal
}
在 Gigraff 中与 POST 参数作斗争 POST
#light "off"
open System.Text.RegularExpressions
open System.IO
open System.Text
open Microsoft.AspNetCore.Http
open Giraffe
open FSharp.Data.Sql
open Giraffe.ViewEngine
let indexView = createPage ("test post") [
...
let row i d = tr [] [
td [] [ str (string(i)) ];
td [] [ str d ]] in
let db_ctx = mssql.GetDataContext() in
let rows = [ for r in db_ctx.Dbo.Data do
(row r.Id r.Data) done ] in
...
form [_method "POST"; _action "/"; _enctype "multipart/form-data"] [
button [] [str "Add row!" ]
input [ _type "text"; _name "Id"]
input [ _type "text"; _name "Data"]
...
div[] rows
]
和
let chk s = not (String.IsNullOrEmpty s)
let indexHandler : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) -> task { return! (
if ctx.Request.ContentType.StartsWith( "multipart/form-data") then begin
let id = (ctx.Request.Form.Item("Id").ToString()) in
let data = (ctx.Request.Form.Item("Data").ToString()) in
if chk id && chk data
&& not (Regex.IsMatch( id,"[^\d]")) then begin
let db_ctx = mssql.GetDataContext() in
db_ctx.Dbo.Data.Create( int(id),data) |> ignore;
db_ctx.SubmitUpdates();
end;
end;
htmlView indexView
) next ctx
}
和
GET >=> route "/" >=> indexHandler;
POST >=> route "/" >=> indexHandler;
假设我们有这个网络服务器来处理请求:
let webApp = scope {
get "/api/zoo/animals/" (getAllAnimals())
getf "/api/zoo/animals/%s" getAnimalInfo
}
此语法在 docs and demoed in the example 中有描述。
现在,如果我想在 url 查询中包含一个参数,例如过滤结果?
http://localhost:8080/api/zoo/animals?type=mammals
这没有做任何事情:
getf "/api/zoo/animals?type=%s" getAnimalsByType
一种方法是使用上下文的函数 GetQueryStringValue
。它returnsResult,一个结构体DU.
因此您保留初始签名(只需删除结尾的斜杠):
get "/api/zoo/animals" (getAnimals())
你有
let getAnimals() : HttpHandler =
fun _ ctx -> task {
let animalTypeFromQuery = ctx.GetQueryStringValue "type"
let animalType =
match animalTypeFromQuery with
| Ok t -> Some t
| Error _ -> None
...
}
我不知道这是否是官方的做法,我在一些 F# github repos 中找到了这种做法。
查看示例:
https://github.com/giraffe-fsharp/Giraffe/blob/master/DOCUMENTATION.md#query-strings
它展示了如何绑定查询字符串中的数据,这样您就不必使用 GetQueryStringValue
在你的情况下,我认为这样的事情可能会奏效。
[<CLIMutable>]
type AnimalType =
{ type : string }
let animal (next : HttpFunc) (ctx : HttpContext) =
// Binds the query string to a Car object
let animal = ctx.BindQueryString<AnimalType>()
// Sends the object back to the client
Successful.OK animal next ctx
let web_app =
router {
pipe_through (pipeline { set_header "x-pipeline-type" "Api" })
post "/api/animal" animal
}
在 Gigraff 中与 POST 参数作斗争 POST
#light "off"
open System.Text.RegularExpressions
open System.IO
open System.Text
open Microsoft.AspNetCore.Http
open Giraffe
open FSharp.Data.Sql
open Giraffe.ViewEngine
let indexView = createPage ("test post") [
...
let row i d = tr [] [
td [] [ str (string(i)) ];
td [] [ str d ]] in
let db_ctx = mssql.GetDataContext() in
let rows = [ for r in db_ctx.Dbo.Data do
(row r.Id r.Data) done ] in
...
form [_method "POST"; _action "/"; _enctype "multipart/form-data"] [
button [] [str "Add row!" ]
input [ _type "text"; _name "Id"]
input [ _type "text"; _name "Data"]
...
div[] rows
]
和
let chk s = not (String.IsNullOrEmpty s)
let indexHandler : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) -> task { return! (
if ctx.Request.ContentType.StartsWith( "multipart/form-data") then begin
let id = (ctx.Request.Form.Item("Id").ToString()) in
let data = (ctx.Request.Form.Item("Data").ToString()) in
if chk id && chk data
&& not (Regex.IsMatch( id,"[^\d]")) then begin
let db_ctx = mssql.GetDataContext() in
db_ctx.Dbo.Data.Create( int(id),data) |> ignore;
db_ctx.SubmitUpdates();
end;
end;
htmlView indexView
) next ctx
}
和
GET >=> route "/" >=> indexHandler;
POST >=> route "/" >=> indexHandler;