Yes, I think HttpPostedFileBase is not supported by EndPoint right now. So instead of putting the file in the endpoint, you need to retrieve it from ctx.Request.Files in your handler.

This would be a nice feature though, worth suggesting on Github.

By on 1/31/2018 2:32 AM ()

Thank you for your answer! Unfortunately, I have not even figured out yet how to send text as FormData. My current source code fails with POST http://localhost:9000/upload 404 (Not Found) when I click the button and I don't really understand why. Thank you for helping me.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
namespace FileUpload
open WebSharper

module Types =
    open WebSharper.Sitelets
    type FileUpload = { [<FormData>] email : string }

[<JavaScript>]
module Client =
    open Types
    open WebSharper.UI.Next.Html
    open WebSharper.JQuery
    open WebSharper.JavaScript
    open WebSharper.UI.Next.Client

    let Main () =
        let ajax (method: string) (url: string) (formData : FileUpload) : Async<string> =
            Async.FromContinuations
                (fun (ok, ko, _) ->
                    JQuery.Ajax(
                        JQuery.AjaxSettings(
                            Url = url,
                            Type = As<JQuery.RequestType> method,
                            ContentType = Union<bool, string>.Union1Of2(false),
                            ProcessData = false,
                            Data = formData,
                            Cache = false,
                            Success = (fun result s q -> JS.Alert("success!"); ok (result :?> string)),
                            Error = (fun result s q -> JS.Alert("failure: " + (result.ResponseText))))
                    )
                    |> ignore
                )

        form
          [ inputAttr
              [ attr.name "email"; attr.``type`` "text" ]
              []
            buttonAttr
              [ on.click (fun _ ev ->
                    ev.PreventDefault()
                    ev.StopPropagation()
                    async {
                        let formData = { email = "hello@world.de"}
                        let! response = ajax "POST" "/upload" formData
                        JS.Alert(response)
                    } |> Async.Start
                )
              ]
              [ text "Submit" ]
          ]

module EndPoints =
    open WebSharper.Sitelets
    open Types
    type EndPoint =
        | [<EndPoint "/">] Home
        | [<EndPoint "POST /upload">] Upload of fileUpload: FileUpload

module Site =
    open WebSharper.UI.Next.Html
    open EndPoints
    open WebSharper.Sitelets
    open WebSharper.UI.Next.Server

    let HomePage (ctx : Context<EndPoint>) =
        Content.Page { Page.Default with Body = [ client <@ Client.Main() @> ] }

    [<Website>]
    let Main =
        Application.MultiPage (fun (ctx : Context<EndPoint>) endpoint ->
            match endpoint with
            | EndPoint.Home ->
                HomePage ctx
            | EndPoint.Upload fileUpload ->
                failwith (sprintf "It works: %A" fileUpload)
        )

module SelfHostedServer =
    open global.Owin
    open Microsoft.Owin.Hosting
    open Microsoft.Owin.StaticFiles
    open Microsoft.Owin.FileSystems
    open WebSharper.Owin

    [<EntryPoint>]
    let Main args =
        let rootDirectory, url = "..", "http://localhost:9000/"
        use server = WebApp.Start(url, fun appB ->
            appB.UseStaticFiles(
                    StaticFileOptions(
                        FileSystem = PhysicalFileSystem(rootDirectory)))
                .UseSitelet(rootDirectory, Site.Main)
            |> ignore)
        stdin.ReadLine() |> ignore
        0
By on 2/2/2018 9:43 AM ()

[<FormData>] is meant to be used directly on the endpoint, i.e. on EndPoint.Upload, and for data passed from <form> elements via action="..." (encoded as application/x-www-form-urlencoded or multipart/form-data).

In your case, you are posting to your /upload endpoint a simple JSON object, but you are trying to receive it as a record. Either add [<Json "xxxx">] on your endpoint, or use [<FormData "xxx">] there and submit to it via <form action="...">.

By on 2/2/2018 3:14 PM ()

Also, for a more JS-heavy alternative, check Kimserey's article Post form data to WebSharper sitelet from HTML/JS.

By on 2/2/2018 3:21 PM ()

It's working now! I guess my problem was that the JavaScript examples I looked at used

1
var formData = new FormData(document.getElementById("formId"));

to create a FormData object and I didn't know how to translate this into WebSharper code. I got the idea to solve this by doing

1
let formData = JS.Eval("""new FormData(document.getElementById("formId"));""")

It works, although it feels quite hacky. Thank you both.

By on 2/3/2018 2:05 AM ()

(Hi Rene - just a quick comment: please use the WebSharper Forums to comment further - FPish and these forums have a different format for storing content, and the old FPish-style markup is being retired in favor of markdown, the format used by the forums. Thanks!)

By on 2/2/2018 2:54 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us
Built with WebSharper