WebSharper - Is there a simple way to catch "not found" routes?
Asked Answered
E

1

6

Is there a simple way of using Sitelets and Application.MultiPage to generate a kind of "default" route (to catch "not found" routes, for example)?

Example

type EndPoint =
    | [<EndPoint "/">] Home
    | [<EndPoint "/about">] About


[<Website>]
let Main =
    Application.MultiPage (fun ctx endpoint ->
        match endpoint with
        | EndPoint.Home -> HomePage ctx
        | EndPoint.About -> AboutPage ctx

I would like to define an EndPoint that could handle requests to anything but "/home" and "/about".

Ebonyeboracum answered 23/9, 2016 at 23:21 Comment(0)
S
2

I just published a bug fix (WebSharper 3.6.18) which allows you to use the Wildcard attribute for this:

type EndPoint =
    | [<EndPoint "/">] Home
    | [<EndPoint "/about">] About
    | [<EndPoint "/"; Wildcard>] AnythingElse of string

[<Website>]
let Main =
    Application.MultiPage (fun ctx endpoint ->
        match endpoint with
        | EndPoint.Home -> HomePage ctx
        | EndPoint.About -> AboutPage ctx
        | EndPoint.AnythingElse path -> Content.NotFound // or anything you want
    )

Note though that this will catch everything, even URLs to files, so for example if you have client-side content then urls like /Scripts/WebSharper/*.js will not work anymore. If you want to do that, then you'll need to drop to a custom router:

type EndPoint =
    | [<EndPoint "/">] Home
    | [<EndPoint "/about">] About
    | AnythingElse of string

let Main =
    Application.MultiPage (fun ctx endpoint ->
        match endpoint with
        | EndPoint.Home -> HomePage ctx
        | EndPoint.About -> AboutPage ctx
        | EndPoint.AnythingElse path -> Content.NotFound // or anything you want
    )

[<Website>]
let MainWithFallback =
    { Main with
        Router = Router.New
            (fun req ->
                match Main.Router.Route req with
                | Some ep -> Some ep
                | None ->
                    let path = req.Uri.AbsolutePath
                    if path.StartsWith "/Scripts/" || path.StartsWith "/Content/" then
                        None
                    else
                        Some (EndPoint.AnythingElse path))
            (function
                | EndPoint.AnythingElse path -> Some (System.Uri(path))
                | a -> Main.Router.Link a)
    }

(copied from my answer in the WebSharper forums)

Sandlin answered 28/9, 2016 at 14:35 Comment(1)
Thanks, @Tarmil! I tried exactly the same code of your first block and it didn't work, but this was before the bug fix. I'm going to try it again :-)Ebonyeboracum

© 2022 - 2024 — McMap. All rights reserved.