diff --git a/atom/anton.tayanovskyy.atom b/atom/anton.tayanovskyy.atom index 2bb63fc..6871bed 100644 --- a/atom/anton.tayanovskyy.atom +++ b/atom/anton.tayanovskyy.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z WebSharper.UI.Next: Declarative Animation diff --git a/atom/btamas.atom b/atom/btamas.atom index 25d0a67..2a714e5 100644 --- a/atom/btamas.atom +++ b/atom/btamas.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Creating a WebSharper binding for Day.js diff --git a/atom/denuziere.atom b/atom/denuziere.atom index 0946636..4ab6664 100644 --- a/atom/denuziere.atom +++ b/atom/denuziere.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Bolero 0.13 released diff --git a/atom/diego.echeverri.atom b/atom/diego.echeverri.atom index 0670fba..7f2b8c9 100644 --- a/atom/diego.echeverri.atom +++ b/atom/diego.echeverri.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Introducing WIG patterns diff --git a/atom/gansperger.atom b/atom/gansperger.atom index 37708e7..535c230 100644 --- a/atom/gansperger.atom +++ b/atom/gansperger.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Try WebSharper: version info about extensions and some embedding improvements diff --git a/atom/granicz.atom b/atom/granicz.atom index 081aa70..b55aa3d 100644 --- a/atom/granicz.atom +++ b/atom/granicz.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Full-stack F# with charting, reactive forms, and more under 300 LOC with WebSharper diff --git a/atom/gygerg.atom b/atom/gygerg.atom index 1b3b899..3d10f9b 100644 --- a/atom/gygerg.atom +++ b/atom/gygerg.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Showcasing Feliz.Engine with WebSharper.React diff --git a/atom/jankoa.atom b/atom/jankoa.atom index d2ebfb1..2261f65 100644 --- a/atom/jankoa.atom +++ b/atom/jankoa.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Compiling to JavaScript dynamically with WebSharper diff --git a/atom/joel.bjornson.atom b/atom/joel.bjornson.atom index 334728e..55ddb91 100644 --- a/atom/joel.bjornson.atom +++ b/atom/joel.bjornson.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z WebSharper Extensions for ExtJS 4 diff --git a/atom/jooseppi12.atom b/atom/jooseppi12.atom index 09a88a4..5ba2188 100644 --- a/atom/jooseppi12.atom +++ b/atom/jooseppi12.atom @@ -3,7 +3,18 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z + + Proxying with WebSharper + + jooseppi1220231211-proxying-with-websharper + fsadvent + fsharp + proxy + websharper + Using the Validus library in WebSharper projects + 2023-12-11T00:00:00Z + Dart in F#, differently diff --git a/atom/maciej.lopatka.atom b/atom/maciej.lopatka.atom index 08159cf..63ecd78 100644 --- a/atom/maciej.lopatka.atom +++ b/atom/maciej.lopatka.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z TinyMCE Extension for WebSharper Released diff --git a/atom/ramon.snir.atom b/atom/ramon.snir.atom index b605732..d3e4cb3 100644 --- a/atom/ramon.snir.atom +++ b/atom/ramon.snir.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z Announcing Formlets for jQuery Mobile diff --git a/atom/sfowler.atom b/atom/sfowler.atom index ebe2c00..6738e56 100644 --- a/atom/sfowler.atom +++ b/atom/sfowler.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z WebSharper UI.Next Version 0.1.31.32 diff --git a/atom/vladimir.matveev.atom b/atom/vladimir.matveev.atom index b0b2df6..9f0d7a2 100644 --- a/atom/vladimir.matveev.atom +++ b/atom/vladimir.matveev.atom @@ -3,7 +3,7 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z WebSharper at Kiev ALT.NET diff --git a/blog/-1/ContentManagedWebSharperAppsWithCustomWebControlsAndTemplating.html b/blog/-1/ContentManagedWebSharperAppsWithCustomWebControlsAndTemplating.html index 93afa6b..691b7f4 100644 --- a/blog/-1/ContentManagedWebSharperAppsWithCustomWebControlsAndTemplating.html +++ b/blog/-1/ContentManagedWebSharperAppsWithCustomWebControlsAndTemplating.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/a-logo-interpreter-under-400-lines.html b/blog/-1/a-logo-interpreter-under-400-lines.html index 68801f7..7bf5559 100644 --- a/blog/-1/a-logo-interpreter-under-400-lines.html +++ b/blog/-1/a-logo-interpreter-under-400-lines.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/compile-to-javascript-dynamically.html b/blog/-1/compile-to-javascript-dynamically.html index 30e3f59..70f411b 100644 --- a/blog/-1/compile-to-javascript-dynamically.html +++ b/blog/-1/compile-to-javascript-dynamically.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/dart-in-fsharp-differently.html b/blog/-1/dart-in-fsharp-differently.html index a860245..9230588 100644 --- a/blog/-1/dart-in-fsharp-differently.html +++ b/blog/-1/dart-in-fsharp-differently.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/data-visualization-with-websharper.html b/blog/-1/data-visualization-with-websharper.html index 6e6627c..3a59581 100644 --- a/blog/-1/data-visualization-with-websharper.html +++ b/blog/-1/data-visualization-with-websharper.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/full-stack-fsharp-with-charting-reactive-forms-and-more-under-300-loc-with-websharper.html b/blog/-1/full-stack-fsharp-with-charting-reactive-forms-and-more-under-300-loc-with-websharper.html index 467c888..3646d7a 100644 --- a/blog/-1/full-stack-fsharp-with-charting-reactive-forms-and-more-under-300-loc-with-websharper.html +++ b/blog/-1/full-stack-fsharp-with-charting-reactive-forms-and-more-under-300-loc-with-websharper.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/introducing-wig-patterns.html b/blog/-1/introducing-wig-patterns.html index a4b0a83..81fc59c 100644 --- a/blog/-1/introducing-wig-patterns.html +++ b/blog/-1/introducing-wig-patterns.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/proxying-with-websharper.html b/blog/-1/proxying-with-websharper.html new file mode 100644 index 0000000..d75f9c1 --- /dev/null +++ b/blog/-1/proxying-with-websharper.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/blog/-1/reactive-forms-with-websharper-forms.html b/blog/-1/reactive-forms-with-websharper-forms.html index cceb36e..d187685 100644 --- a/blog/-1/reactive-forms-with-websharper-forms.html +++ b/blog/-1/reactive-forms-with-websharper-forms.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/showcasing-feliz-engine-with-websharper-react.html b/blog/-1/showcasing-feliz-engine-with-websharper-react.html index c4ccdbf..a9399ce 100644 --- a/blog/-1/showcasing-feliz-engine-with-websharper-react.html +++ b/blog/-1/showcasing-feliz-engine-with-websharper-react.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/starting-with-websharper-interface-generator.html b/blog/-1/starting-with-websharper-interface-generator.html index ef374ad..15a69aa 100644 --- a/blog/-1/starting-with-websharper-interface-generator.html +++ b/blog/-1/starting-with-websharper-interface-generator.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/variations-for-a-websharper-shopping-cart.html b/blog/-1/variations-for-a-websharper-shopping-cart.html index 0011340..703dfa3 100644 --- a/blog/-1/variations-for-a-websharper-shopping-cart.html +++ b/blog/-1/variations-for-a-websharper-shopping-cart.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/wig-tutorial-dayjs.html b/blog/-1/wig-tutorial-dayjs.html index 8afc9ae..a8521c4 100644 --- a/blog/-1/wig-tutorial-dayjs.html +++ b/blog/-1/wig-tutorial-dayjs.html @@ -1,7 +1,7 @@  - + diff --git a/blog/-1/wig-tutorial-momentjs.html b/blog/-1/wig-tutorial-momentjs.html index fdac95f..2214fd6 100644 --- a/blog/-1/wig-tutorial-momentjs.html +++ b/blog/-1/wig-tutorial-momentjs.html @@ -1,7 +1,7 @@  - + diff --git a/blogs.html b/blogs.html index 516e184..dd437bd 100644 --- a/blogs.html +++ b/blogs.html @@ -128,8 +128,8 @@

IntelliFactory blogs

Articles

F# -

290

-

+1 This year +

291

+

+2 This year

@@ -158,7 +158,7 @@

IntelliFactory blogs

Bloggers

-
Adam GraniczAndras JankoJozsef UriTamas BankaLoic DenuziereIstvan GanspergerSimon FowlerAnton TayanovskyyRamon SnirJoel BjornsonMaciej LopatkaVladimir MatveevDiego EcheverriGergely FabianSandor SzalokyAdam Abonyi-Toth
+
Gergo GyalusAdam GraniczAndras JankoTamas BankaLoic DenuziereIstvan GanspergerSimon FowlerAnton TayanovskyyRamon SnirJoel BjornsonMaciej LopatkaVladimir MatveevDiego EcheverriGergely FabianSandor SzalokyAdam Abonyi-Toth
  • @@ -192,6 +192,17 @@

    F# Advent
    -
    -
    -
    -
    -
    +
    Gergo Gyalus
    Gergo Gyalus
    diff --git a/feed.atom b/feed.atom index 844e38f..8f91d8a 100644 --- a/feed.atom +++ b/feed.atom @@ -3,7 +3,18 @@ IntelliFactory Blog Building F# applications since 2004 - 2023-12-08T20:43:53Z + 2023-12-12T22:24:40Z + + Proxying with WebSharper + + jooseppi1220231211-proxying-with-websharper + fsadvent + fsharp + proxy + websharper + Using the Validus library in WebSharper projects + 2023-12-11T00:00:00Z + Showcasing Feliz.Engine with WebSharper.React diff --git a/feed.rss b/feed.rss index 00180e8..967e2c9 100644 --- a/feed.rss +++ b/feed.rss @@ -4,7 +4,18 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC + + Proxying with WebSharper + https://intellifactory.com/user/jooseppi12/20231211-proxying-with-websharper + jooseppi1220231211-proxying-with-websharper + fsadvent + fsharp + proxy + websharper + Using the Validus library in WebSharper projects + Mon, 11 Dec 2023 00:00:00 UTC + Showcasing Feliz.Engine with WebSharper.React https://intellifactory.com/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react diff --git a/rss/anton.tayanovskyy.rss b/rss/anton.tayanovskyy.rss index db513f8..934d075 100644 --- a/rss/anton.tayanovskyy.rss +++ b/rss/anton.tayanovskyy.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC WebSharper.UI.Next: Declarative Animation https://intellifactory.com/user/anton.tayanovskyy/20140721-websharper-ui-next-declarative-animation diff --git a/rss/btamas.rss b/rss/btamas.rss index c1dd978..a4c2a28 100644 --- a/rss/btamas.rss +++ b/rss/btamas.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Creating a WebSharper binding for Day.js https://intellifactory.com/user/btamas/20211221-wig-tutorial-dayjs diff --git a/rss/denuziere.rss b/rss/denuziere.rss index 54c0284..461fdf3 100644 --- a/rss/denuziere.rss +++ b/rss/denuziere.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Bolero 0.13 released https://intellifactory.com/user/denuziere/20200523-bolero-0-13-released diff --git a/rss/diego.echeverri.rss b/rss/diego.echeverri.rss index 9b92adf..029bb03 100644 --- a/rss/diego.echeverri.rss +++ b/rss/diego.echeverri.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Introducing WIG patterns https://intellifactory.com/user/diego.echeverri/20101022-introducing-wig-patterns diff --git a/rss/gansperger.rss b/rss/gansperger.rss index 22a3a7a..14eb8c7 100644 --- a/rss/gansperger.rss +++ b/rss/gansperger.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Try WebSharper: version info about extensions and some embedding improvements https://intellifactory.com/user/gansperger/20151006-try-websharper-version-info-about-extensions-and-some-embedding-improvements diff --git a/rss/granicz.rss b/rss/granicz.rss index d3acd9b..3cfd4f7 100644 --- a/rss/granicz.rss +++ b/rss/granicz.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Full-stack F# with charting, reactive forms, and more under 300 LOC with WebSharper https://intellifactory.com/user/granicz/20221229-full-stack-fsharp-with-charting-reactive-forms-and-more-under-300-loc-with-websharper diff --git a/rss/gygerg.rss b/rss/gygerg.rss index 3f9fc37..653d488 100644 --- a/rss/gygerg.rss +++ b/rss/gygerg.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Showcasing Feliz.Engine with WebSharper.React https://intellifactory.com/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react diff --git a/rss/jankoa.rss b/rss/jankoa.rss index 6aaf462..b7fbc1d 100644 --- a/rss/jankoa.rss +++ b/rss/jankoa.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Compiling to JavaScript dynamically with WebSharper https://intellifactory.com/user/jankoa/20221223-compile-to-javascript-dynamically diff --git a/rss/joel.bjornson.rss b/rss/joel.bjornson.rss index 2af63bd..4e9b949 100644 --- a/rss/joel.bjornson.rss +++ b/rss/joel.bjornson.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC WebSharper Extensions for ExtJS 4 https://intellifactory.com/user/joel.bjornson/20110724-websharper-extensions-for-extjs-4 diff --git a/rss/jooseppi12.rss b/rss/jooseppi12.rss index 2f2b73b..f66764b 100644 --- a/rss/jooseppi12.rss +++ b/rss/jooseppi12.rss @@ -4,7 +4,18 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC + + Proxying with WebSharper + https://intellifactory.com/user/jooseppi12/20231211-proxying-with-websharper + jooseppi1220231211-proxying-with-websharper + fsadvent + fsharp + proxy + websharper + Using the Validus library in WebSharper projects + Mon, 11 Dec 2023 00:00:00 UTC + Dart in F#, differently https://intellifactory.com/user/jooseppi12/20221215-dart-in-fsharp-differently diff --git a/rss/maciej.lopatka.rss b/rss/maciej.lopatka.rss index 0f516ac..0baac68 100644 --- a/rss/maciej.lopatka.rss +++ b/rss/maciej.lopatka.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC TinyMCE Extension for WebSharper Released https://intellifactory.com/user/maciej.lopatka/20110722-tinymce-extension-for-websharper-released diff --git a/rss/ramon.snir.rss b/rss/ramon.snir.rss index 1834971..4fe344d 100644 --- a/rss/ramon.snir.rss +++ b/rss/ramon.snir.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC Announcing Formlets for jQuery Mobile https://intellifactory.com/user/ramon.snir/20110909-announcing-formlets-for-jquery-mobile diff --git a/rss/sfowler.rss b/rss/sfowler.rss index 1c721dd..3d9f713 100644 --- a/rss/sfowler.rss +++ b/rss/sfowler.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC WebSharper UI.Next Version 0.1.31.32 https://intellifactory.com/user/sfowler/20140819-websharper-ui-next-version-0-1-31-32 diff --git a/rss/vladimir.matveev.rss b/rss/vladimir.matveev.rss index 4243072..2dc3075 100644 --- a/rss/vladimir.matveev.rss +++ b/rss/vladimir.matveev.rss @@ -4,7 +4,7 @@ IntelliFactory Blog Building F# applications since 2004 https://intellifactory.com - Fri, 08 Dec 2023 20:43:53 UTC + Tue, 12 Dec 2023 22:24:40 UTC WebSharper at Kiev ALT.NET https://intellifactory.com/user/vladimir.matveev/20110220-websharper-at-kiev-alt-net diff --git a/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react.html b/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react.html index fe6e9b5..e0c7662 100644 --- a/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react.html +++ b/user/gygerg/20231208-showcasing-feliz-engine-with-websharper-react.html @@ -420,7 +420,13 @@

    You might also be intere

    -
    Gergo Gyalus
    Found a typo?
    diff --git a/user/jooseppi12.html b/user/jooseppi12.html index bc432e6..8fc4ebe 100644 --- a/user/jooseppi12.html +++ b/user/jooseppi12.html @@ -140,6 +140,12 @@

    Articles to date

    Jozsef Uri
    Jozsef Uri
    diff --git a/user/jooseppi12/20231211-proxying-with-websharper.html b/user/jooseppi12/20231211-proxying-with-websharper.html new file mode 100644 index 0000000..74f035a --- /dev/null +++ b/user/jooseppi12/20231211-proxying-with-websharper.html @@ -0,0 +1,469 @@ + + + + + + Proxying with WebSharper + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    + +
    +
    +
    +

    Proxying with WebSharper

    +
    +
    +
    +
    +
    +
    +
    Jozsef Uri +
    +

    Jozsef Uri

    +

    Dec 11, 2023

    +
    +
    +

    Reading time:

    +

    9 mins

    +
    +
    +

    Share via:

    + +
    +
    +
    +
    +
    +
    +
    +

    I was using the Validus library in a non-web project, when I realized it would be quite useful to leverage its functionality in the browser as well. I'm using WebSharper and I was not aware of a Validus binding for it, so at first this seemed like a no-go. But here is where WebSharper proxies come to the rescue! But before then, let's start with an alternate approach that feels like the right approach, and then conclude why it's not optimal and why proxies are the right tool after all.

    +

    First attempt: using the source and translating it to JavaScript

    +

    As Validus is open source, it's tempting to just compile it to JavaScript. I can grab the source code (say, via a git submodule), create a new WebSharper library project (be sure to install WebSharper.Templates via dotnet new install WebSharper.Templates, then dotnet new websharper-lib -lang F# -n AsJavascriptLib), and add the existing source files to it.

    +

    So my project file has a section like this:

    +
    <ItemGroup>
    +  <Compile Include="../Validus/src/Validus/Core.fs" />
    +  <Compile Include="../Validus/src/Validus/Validators.fs" />
    +  <Compile Include="../Validus/src/Validus/Validators.Default.fs" />
    +  <Compile Include="../Validus/src/Validus/Check.fs" />
    +  <Compile Include="../Validus/src/Validus/Operators.fs" />
    +  <None Include="wsconfig.json" />
    +</ItemGroup>
    +
    +

    Here is where things start to go south: when I try to compile this, WebSharper tells me that it can't translate Regex.IsMatch from the BCL:

    +

    Error without the proxy

    +

    What is the problem with this?

    +

    I can of course rewrite the missing BCL calls and get my JavaScript library, plug it into my JavaScript/TypeScript projects, and all would be OK. But my intention was to use Validus in my WebSharper applications, and by making it into a new WebSharper library I essentially recreated everything as new .NET types, instead of telling the compiler how to translate the existing types (from the Validus assembly) to JavaScript. This means that if we want to reuse functionality both on the client and server side, we are not working with the same types, making things more complicated than what they should be.

    +

    Solution: use a proxy!

    +

    A WebSharper proxy is a type that tells the compiler how to compile another .NET type into JavaScript.

    +

    Next to library projects, WebSharper.Templates also features a websharper-prx project template for proxy projects. All you need to proxy .NET libraries is to create your proxy project with dotnet new websharper-prx -lang F# -n ProxyProject and add your proxies to it.

    +

    Given our earlier prototype, instead of creating a new project, we can simply convert it to a proxy project by changing the content of wsconfig.json to this:

    +
    {
    +  "$schema": "https://websharper.com/wsconfig.schema.json",
    +  "project": "proxy",
    +  "proxyTargetName": "Validus"
    +}
    +
    +

    and adding a Proxy.fs to the project file:

    +
    <ItemGroup>
    +  ...
    +  <Compile Include="Proxy.fs" />
    +<ItemGroup>
    +
    +

    The key here is the proxyTargetName setting, which tells the compiler what assembly we want to translate to JavaScript.

    +

    What if I don't have access to a library's source code?

    +

    Going back to our Validus experiment, we found that is uses IsMatch from System.Text.RegularExpressions.Regex, which WebSharper fails to translate. But now, we can tell the compiler how to translate it with the help of the Proxy attribute.

    +

    ProxyAttribute tells the compiler how to translate a piece of .NET code to JavaScript. So to proxy the missing function from RegularExpressions that Validus uses, we can simply add the following to Proxy.fs, redirecting to the standard JavaScript regex functionality (we will not be trying to bridge the differences between JavaScript and .NET regexes in this article):

    +
    open WebSharper.JavaScript
    +
    +[<Proxy(typeof<System.Text.RegularExpressions.Regex>)>]
    +type internal RegexProxy =
    +    static member IsMatch(toMatch: string, pattern: string) = RegExp(pattern).Test toMatch
    +
    +

    With this tiny addition, we can now build our proxy project and use it along Validus itself in any WebSharper project. In general, you should mark proxies to be internal or private, as they themselves shouldn't be used/referenced directly. To avoid possible pitfalls, if a proxy is marked as public, the compiler will warn about it.

    +

    Let's see it in action!

    +

    Alas - we can finally reap the benefits of Validus in a WebSharper app! To use our proxy project we need to include both the original Validus library and our new proxy project, like this:

    +
    <ItemGroup>
    +  <PackageReference Include="WebSharper" Version="7.0.3.364-beta3" />    
    +  <PackageReference Include="WebSharper.FSharp" Version="7.0.3.364-beta3" />
    +  <PackageReference Include="Validus" Version="4.1.3" />
    +</ItemGroup>
    +
    +<ItemGroup>
    +  <ProjectReference Include="../ProxyProject/ProxyProject.fsproj"></ProjectReference>
    +</ItemGroup>
    +
    +

    After that we can take the example from the Validus README:

    +
    let ofDto (dto : PersonDto) =
    +    // A basic validator
    +    let nameValidator =
    +        Check.String.betweenLen 3 64
    +
    +    // Composing multiple validators to form complex validation rules,
    +    // overriding default error message (Note: "Check.WithMessage.String" as
    +    // opposed to "Check.String")
    +    let emailValidator =
    +        let emailPatternValidator =
    +            let msg = sprintf "Please provide a valid %s"
    +            Check.WithMessage.String.pattern @"[^@]+@[^\.]+\..+" msg
    +
    +        ValidatorGroup(Check.String.betweenLen 8 512)
    +            .And(emailPatternValidator)
    +            .Build()
    +
    +    // Defining a validator for an option value
    +    let ageValidator =
    +        Check.optional (Check.Int.between 1 100)
    +
    +    // Defining a validator for an option value that is required
    +    let dateValidator =
    +        Check.required (Check.DateTime.greaterThan DateTime.Now)
    +
    +    validate {
    +        let! first = nameValidator "First name" dto.FirstName
    +        and! last = nameValidator "Last name" dto.LastName
    +        and! email = emailValidator "Email address" dto.Email
    +        and! age = ageValidator "Age" dto.Age
    +        and! startDate = dateValidator "Start Date" dto.StartDate
    +
    +        // Construct Person if all validators return Success
    +        return {
    +            Name = { First = first; Last = last }
    +            Email = email
    +            Age = age
    +            StartDate = startDate }
    +        }
    +
    +

    and use it in our Main function to populate some content in our HTML:

    +
    [<SPAEntryPoint>]
    +let Main () =
    +    let scenario1, single_err =
    +        {
    +            FirstName = "John"
    +            LastName  = "John"
    +            Email     = "john@john"
    +            Age       = Some 15
    +            StartDate = Some (DateTime(2035,12,01))
    +        }
    +        |> fun d -> d, Person.ofDto d
    +
    +    let scenario2, multi_err =
    +        {
    +            FirstName = "John"
    +            LastName  = "Doe"
    +            Email     = "john"
    +            Age       = None
    +            StartDate = Some (DateTime(1999,12,01))
    +        }
    +        |> fun d -> d, Person.ofDto d
    +
    +    let scenario3, ok =
    +        {
    +            FirstName = "John"
    +            LastName  = "Doe"
    +            Email     = "john@doe.com"
    +            Age       = Some 15
    +            StartDate = Some (DateTime(2035,12,01))
    +        }
    +        |> fun d -> d, Person.ofDto d
    +
    +    let resolveValidation (r: Result<Person, ValidationErrors>) =
    +        match r with
    +        | Result.Ok _ ->
    +            "OK"
    +        | Result.Error errors ->
    +            ValidationErrors.toList errors
    +            |> String.concat "\n"
    +
    +    let s1, r1 = JS.Document.QuerySelector "#sample_singleerr > div:first-of-type", JS.Document.QuerySelector "#sample_singleerr > div:last-of-type"
    +    let s2, r2 = JS.Document.QuerySelector "#sample_multierr > div:first-of-type", JS.Document.QuerySelector "#sample_multierr > div:last-of-type"
    +    let s3, r3 = JS.Document.QuerySelector "#sample_ok > div:first-of-type", JS.Document.QuerySelector "#sample_ok > div:last-of-type"
    +
    +    s1.TextContent <- sprintf "%A" <| scenario1.PrettyPrint()
    +    s2.TextContent <- sprintf "%A" <| scenario2.PrettyPrint()
    +    s3.TextContent <- sprintf "%A" <| scenario3.PrettyPrint()
    +
    +    r1.TextContent <- resolveValidation single_err
    +    r2.TextContent <- resolveValidation multi_err
    +    r3.TextContent <- resolveValidation ok
    +
    +

    Combining this with some simple markup (part of index.html):

    +
    <h2>Single error example</h2>
    +<div id="sample_singleerr" class="scenario">
    +    <div></div>
    +    <div class="error"></div>
    +</div>
    +<h2>Multi error example</h2>
    +<div id="sample_multierr" class="scenario">
    +    <div></div>
    +    <div class="error"></div>
    +</div>
    +<h2>OK example</h2>
    +<div id="sample_ok" class="scenario">
    +    <div></div>
    +    <div class="ok"></div>
    +</div>
    +
    +

    We will get the validation by Validus running in our browser with WebSharper:

    +

    Image of sample site

    +

    Closure

    +

    All the code used in this blog entry can be found in this repository, and the sample project is also deployed live here. Please note that in order to run the application on your machine, you will need to add the WebSharper GitHub packages feed to your NuGet sources - see this page for more details.

    +

    Thanks to Sergey Tihon for organizing F# Advent in 2023 again, and I hope that you find this article useful!

    +
    +
    +
    +
    +
    +
    +
    +

    Read more from

    +
    +
    +

    Can’t find what you were looking for? Drop us a line. + +

    +
    +
    +
    +
    +
    Jozsef Uri +
    Found a typo?
    +
    +

    This blog post is hosted on GitHub here. Feel free to file a ticket or send a PR.

    +
    + + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    IntelliFactory

    + +
    + +
    +

    Open Source

    + +
    +
    +
    +
    +

    Newsletter

    +
    +
    + + + + + + + +
    +
    +

    We will not spam you or give your details to anyone.

    +
    +
    +
    +
    + + +
    +
    +
    + +
    + + + + + +
    +
    + + \ No newline at end of file diff --git a/user/maciej.lopatka/20110722-tinymce-extension-for-websharper-released.html b/user/maciej.lopatka/20110722-tinymce-extension-for-websharper-released.html index dfacb0d..e4fce64 100644 --- a/user/maciej.lopatka/20110722-tinymce-extension-for-websharper-released.html +++ b/user/maciej.lopatka/20110722-tinymce-extension-for-websharper-released.html @@ -249,7 +249,13 @@

    You might also be intere