Hello,

Thanks for your help. I have aboided client server as creating a REST API seemed overkill. Traditionally I would just do the work server side, generate the from end html (it doesn't need to be dynamic) and serve that up. So now the client needs to make a call to the server instead of doing it all in the back end?

Thank you

Russ

By on 12/5/2016 9:36 PM ()

You probably want to use client server RPC. I really like the ability to generate the HTML from the sitelet and attach the client side code with RPC calls to submit data and receive additional data. It makes everything clean and easy.

By on 12/7/2016 3:11 PM ()

I have it working now, and you're right it's certainly clean and easy. To me it feels like extra work for the machines, but as a friend pointed out to me websharper wasn't built to solve the problem the way I was imagining it should. If I find a way to do it server side without a client side call I'll post the answer. Thanks

By on 12/7/2016 11:39 PM ()
By on 12/5/2016 10:34 PM ()

Go ahead and choose a self-hosted a client server application. You are going to want to spend your time defining sitelets for your REST API Self hosted uses OWIN and httplistener which is supported on mono. I have no problem moving projects that I build in Visual studios on to my production linux boxes. Note that getting https to work with httplistener can be tricky.

Also you may need to enable CORS if you want other websites with Javascript to use the data. CORS

By on 12/5/2016 4:04 PM ()

There is a number of methods to enable CORS on RPC calls (e.g. WebSharper.Web.Remoting.AddAllowedOrigin(string origin) ). But they do not work for Sitelet calls. Does the Websharper have some API to enable CORS on Sitelet or developer should implement it himself?

By on 7/5/2018 4:56 AM ()

Hi, sorry for taking so long to reply.

Right now there isn't a way to enable the CORS checks we have on RPCs to Sitelets. But it is definitely an improvement that we should add. I'll submit an issue for it on github, and start thinking about the best way to handle it; there are multiple aspects to take into consideration, such as preflight OPTIONS requests.

In the meantime you can use something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module Content =
    open WebSharper.Web

    let CheckCors (ctx: Context<'T>) (acceptedMethods: seq<string>) (mkContent: unit -> Async<Content<'T>>) =
        match RpcHandler.CorsAndCsrfCheck
                <| ctx.Request.Method.ToString()
                <| ctx.RequestUri
                <| fun s ->
                    ctx.Request.Cookies.[s]
                <| fun n ->
                    ctx.Request.Headers
                    |> Seq.tryPick (fun h -> if h.Name = n then Some h.Value else None)
                <| fun k v ->
                    // If you're on ASP.NET:
                    // open System.Web
                    let hctx = ctx.Environment.["HttpContext"] :?> HttpContextBase
                    HttpCookie(k, v, Expires = DateTime.UtcNow.AddYears(1000))
                    |> hctx.Response.SetCookie

                    // If you're on OWIN:
                    // open Microsoft.Owin
                    let octx = OwinContext(ctx.Environment)
                    octx.Response.Cookies.Append(k, v,
                        CookieOptions(Expires = Nullable(DateTime.UtcNow.AddYears(1000))))

                    // If you're on ASP.NET Core:
                    // open Microsoft.AspNetCore.Http
                    let hctx = ctx.Environment.["HttpContext"] :?> HttpContext
                    hctx.Response.Cookies.Append(k, v,
                        CookieOptions(Expires = Nullable(DateTimeOffset.UtcNow.AddYears(1000))))
            with
        | CorsAndCsrfCheckResult.Ok headers ->
            mkContent()
            |> Content.WithHeaders [for k, v in headers -> Http.Header.Custom k v]
            |> Content.WithHeader "Access-Control-Allow-Methods" (String.concat "," acceptedMethods)
        | CorsAndCsrfCheckResult.Preflight headers ->
            Content.Ok
            |> Content.WithHeaders [for k, v in headers -> Http.Header.Custom k v]
            |> Content.WithHeader "Access-Control-Allow-Methods" (String.concat "," acceptedMethods)
        | CorsAndCsrfCheckResult.Error (code, status, txt) ->
            Content.Text txt
            |> Content.SetStatus (Http.Status.Custom code (Some status))

which you can use as follows:

1
2
3
4
5
6
7
8
9
10
11
type EndPoint =
    | [<EndPoint "/cors-protected"; Method("PUT", "OPTIONS")>] CorsProtected

let Main =
    Remoting.AddAllowedOrigin("http://my-origin")
    Application.MultiPage(fun (ctx: Context<_>) ep ->
        match ep with
        | CorsProtected ->
            Content.CheckCors ctx ["PUT"] <| fun () ->
                Content.Text "OK!!!"
    )

Ultimately I'll try to add to the library a method that requires less code from the user's part, ie. without having to specify "OPTIONS" on your endpoint definition and repeat "PUT" on the CORS check.

By on 8/1/2018 2:22 AM ()
By on 8/1/2018 2:44 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper