0

I have tried to create HtmlHelper for MVC 5 app in F# my implementation is following:

namespace FSharpStore.WebUI.HtmlHelpers

module PagingHelpers =
type HtmlHelper with
    static member PageLinks(info: PagingInfo, url : UrlHelper) : MvcHtmlString =
        let pageUrl x = url.Action("List", x.ToString())

        let sb = new StringBuilder()
        for i in 0..info.TotalPages do
            let tag = new TagBuilder("a") 
            tag.MergeAttribute("href", pageUrl(i))
            tag.InnerHtml <- i.ToString()
            if i = info.CurrentPage then
                tag.AddCssClass("selected")
                tag.AddCssClass("btn-primary")

            tag.AddCssClass("btn btn-default")
            sb.Append(tag.ToString()) |> ignore

        MvcHtmlString.Create(sb.ToString())

and I have tried used it in view accordingly:

@using FSharpStore.WebUI.HtmlHelpers <div class="btn-group pull-right"> @Html.PageLinks(Model.PagingInfo, this.Url) </div>

Code is not compilable and it give me message : 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'PageLinks' and no extension method 'PageLinks' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?)

Have anyone done HtmlHelper in F# successfully? I have tried used code extensions in difference part of project and they are just working. I think it's something special with razor itself.

Martin Bodocky
  • 651
  • 1
  • 5
  • 16

2 Answers2

0

I think in order for it to work as a static extension method you will need to nest it in a type that has the [<Extension>] attribute. Also the method itself should then be decorated with the [<Extension>] attribute. Also, in the page you are trying to use it from, have you actually imported the module you are trying to access in the using statements?

Martin
  • 920
  • 7
  • 24
0

Your code is a valid F# extension method. But this will be only visible for F#. In order to use your extension methods in C# you must use the "C# way". So, the HtmlHelper code:

namespace FsCsMvc41WeApp.Helpers
open System.Runtime.CompilerServices
open System.Web;
open System.Web.Mvc;

[<Extension>]
type MyHelpers = 
    [<Extension>]
    static member sayHello(helper : HtmlHelper, name: string) =
        new HtmlString("Hello " + name)

And the Razor view:

@using FsCsMvc41WeApp.Helpers
@{
    Layout = null;

}
<!DOCTYPE html>
<html>
<head>
    <title>Index</title>
</head>
<body>
    <div>
        @Html.sayHello("Nicolás")
    </div>
</body>
</html>