【问题标题】:websharper F# endpoints - catch all page handler and page redirectwebsharper F# 端点 - 捕获所有页面处理程序和页面重定向
【发布时间】:2026-01-26 08:35:01
【问题描述】:

抱歉这篇文章太长了

我正在使用 F# 和 WebSharper(我对这两种技术都是新手)

我定义了一些端点(在添加 NotFound 端点之前我有工作代码)

type EndPoint =
    | [<EndPoint "/">] Home
    | [<EndPoint "/login">] Login
    | [<EndPoint "/about">] About
    | [<EndPoint "/logout">] Logout

    // trying to make a catch-all page handler
    | [<EndPoint "/"; Wildcard>] NotFound of string 
...
let HomePage ctx =
    Templating.Main ctx EndPoint.Home "Home" [
        // page stuff
    ]

let LoginPage ctx =
    Templating.Main ctx EndPoint.Login "Login" [
        h1 [] [text "Login Here"]
        div [] [client <@ Client.LoginWidget() @>]
    ]

// other page constructs
let MissingPage ctx path =
    Templating.Main ctx EndPoint.About "Page Not Found" [
        h1 [] [text "404"]
        p [] [text "The requested page could not be found"]
        p [] [text path]
    ]
...
[<Website>]
let Main =
    Application.MultiPage (fun ctx endpoint ->
        match endpoint with
        | EndPoint.Home -> HomePage ctx
        | EndPoint.About -> AboutPage ctx
        | EndPoint.Login -> LoginPage ctx
        | EndPoint.Logout -> 
            async {
                // call server-side code to log the user out
                // what would i do here to redirect the user to the /login 
                // page
            }
        | EndPoint.NotFound path -> MissingPage ctx path
    )

添加 NotFound 端点会弄乱我的其他页面,例如,我的主页开始由 MissingPage 处理程序处理。我可以理解,因为主页设置为匹配“/”并且非模式匹配“/”通配符,尽管我希望单个 / 匹配 Home 端点以及除 /Login /About 之外的任何其他内容和/Logout 以匹配 NotFound 分支。但很明显,我没有正确理解某些内容。

那么我怎样才能获得一个“包罗万象”类型的端点,以便我可以正确处理任何未明确满足的路径

当我有 NotFound 处理代码时,另一件搞砸的事情是登录处理程序不再处理

div [] [client <@ Client.LoginWidget() @>]

最后,在注销处理程序中,我想调用一些服务器端代码(没问题),但是我应该怎么做才能重定向到新网页,例如,将用户发送回 /login页面?

再次抱歉这么长的帖子 德里克

【问题讨论】:

    标签: f# endpoints websharper websharper.ui.next


    【解决方案1】:

    以下内容基于 websharper.com 的 Loïc 传递给我的内容,并在此处添加以防对其他人有帮助。

    需要第一个 Web.config

    <httpErrors errorMode="Custom">
      <remove statusCode="404"/>
      <error statusCode="404" responseMode="ExecuteURL" path="/notfound"/>
    </httpErrors>
    
    type EndPoint = 
    ... other end points
    | [<EndPoint "/notfound"; Wildcard>] NotFound of string
    
    
    [<Website>]
    let Main =
        Application.MultiPage (fun ctx endpoint ->
            match endpoint with
            // handle other endpoints
            // Handle none existant paths
            | EndPoint.NotFound _ ->
                // Parse the original URI from ASP.NET's rewrite, in case you need it
                let requestedUri =
                    let q = ctx.RequestUri.Query
                    let q = q.[q.IndexOf(';') + 1 ..]
                    match System.Uri.TryCreate(q, System.UriKind.Absolute) with
                    // The request was to /notfound/... directly
                    | false, _ -> ctx.RequestUri
                    // The request was to a non-existent path, and rewritten by ASP.NET
                    | true, uri -> uri
    
              Content.Text (sprintf "Unknown URI: %A" requestedUri)
              |> Content.SetStatus Http.Status.NotFound
    
    ...
    

    【讨论】: