|
| 1 | +namespace WebApiContrib.Formatting.Razor |
| 2 | + |
| 3 | +#if INTERACTIVE |
| 4 | +#I "../packages" |
| 5 | +#r "System.Net.Http" |
| 6 | +#r "Microsoft.AspNet.Mvc.5.0.0/lib/net45/System.Web.Mvc.dll" |
| 7 | +#r "Microsoft.AspNet.Razor.3.0.0/lib/net45/System.Web.Razor.dll" |
| 8 | +#r "Microsoft.AspNet.WebApi.Client.5.0.0/lib/net45/System.Net.Http.Formatting.dll" |
| 9 | +#r "Microsoft.AspNet.WebApi.Core.5.0.0/lib/net45/System.Web.Http.dll" |
| 10 | +#r "RazorEngine.3.3.0/lib/net40/RazorEngine.dll" |
| 11 | +#r "WebApiContrib.Formatting.Html.2.0.0/lib/net45/WebApiContrib.Formatting.Html.dll" |
| 12 | +#endif |
| 13 | + |
| 14 | +open System |
| 15 | +open System.Collections.Generic |
| 16 | +open System.IO |
| 17 | +open System.Web |
| 18 | +open System.Web.Mvc |
| 19 | +open System.Web.Routing |
| 20 | +open RazorEngine.Configuration |
| 21 | +open RazorEngine.Templating |
| 22 | +open RazorEngine.Text |
| 23 | + |
| 24 | +/// <summary> |
| 25 | +/// A <see cref="TemplateBase"/> class for use when rendering HTML with Razor in Web API applications. |
| 26 | +/// </summary> |
| 27 | +/// <typeparam name="T">The Model type.</typeparam> |
| 28 | +[<AbstractClass>] |
| 29 | +[<RequireNamespaces("System.Web.Mvc.Html")>] |
| 30 | +type HtmlTemplateBase<'T>() = |
| 31 | + inherit TemplateBase<'T>() |
| 32 | + |
| 33 | + let urlHelper = lazy (new System.Web.Http.Routing.UrlHelper()) |
| 34 | + let mutable viewData : ViewDataDictionary = null |
| 35 | + |
| 36 | + /// <summary> |
| 37 | + /// Writes markup to the specified <paramref name="writer"/>, encoding by default |
| 38 | + /// except in cases where the <paramref name="value"/> is already encoded. |
| 39 | + /// </summary> |
| 40 | + /// <param name="writer">The current <see cref="TextWriter"/>.</param> |
| 41 | + /// <param name="value">The value to write to the <paramref name="writer"/>.</param> |
| 42 | + /// <see href="http://stackoverflow.com/questions/19431365/razorengine-html-helpers-work-but-escape-the-html"/> |
| 43 | + override this.WriteTo(writer: TextWriter, value: obj) = |
| 44 | + if writer = null then |
| 45 | + raise (new ArgumentNullException("writer")) |
| 46 | + |
| 47 | + if value = null then () else |
| 48 | + let valueType = value.GetType() |
| 49 | + if typeof<IEncodedString>.IsAssignableFrom(valueType) then |
| 50 | + let encodedString = unbox<IEncodedString> value |
| 51 | + writer.Write(encodedString) |
| 52 | + elif typeof<IHtmlString>.IsAssignableFrom(valueType) then |
| 53 | + let htmlString = unbox<IHtmlString> value |
| 54 | + writer.Write(htmlString.ToHtmlString()) |
| 55 | + else |
| 56 | + // This was the base template's implementation: |
| 57 | + writer.Write(this.TemplateService.EncodedStringFactory.CreateEncodedString(value)) |
| 58 | + |
| 59 | + /// <summary> |
| 60 | + /// Returns a <see cref="System.Web.Mvc.HtmlHelper{T}"/> based on the current Model type. |
| 61 | + /// </summary> |
| 62 | + member this.Html = |
| 63 | + // NOTE: Removed caching, as that would block updates the ViewData property, which has a setter. |
| 64 | + let writer = this.CurrentWriter |
| 65 | + let viewContext = new ViewContext(Writer = writer, ViewData = this.ViewData) |
| 66 | + new HtmlHelper<'T>(viewContext, this) |
| 67 | + |
| 68 | + /// <summary> |
| 69 | + /// Returns a <see cref="System.Web.Http.Routing.UrlHelper"/>. |
| 70 | + /// </summary> |
| 71 | + /// <remarks> |
| 72 | + /// This is not currently tied to the current <see cref="System.Net.Http.HttpRequestMessage"/> but should be. |
| 73 | + /// </remarks> |
| 74 | + member this.Url = urlHelper.Force() |
| 75 | + |
| 76 | + /// <summary> |
| 77 | + /// Returns a <see cref="ViewDataDictionary"/> typed to the Model's type. |
| 78 | + /// </summary> |
| 79 | + member this.ViewData |
| 80 | + with get() : ViewDataDictionary = |
| 81 | + if viewData = null then |
| 82 | + viewData <- new ViewDataDictionary<'T>(TemplateInfo = new TemplateInfo(HtmlFieldPrefix = ""), Model = this.Model) |
| 83 | + viewData |
| 84 | + and set(value) = |
| 85 | + viewData <- value |
| 86 | + |
| 87 | + interface IViewDataContainer with |
| 88 | + member this.ViewData |
| 89 | + with get() = this.ViewData |
| 90 | + and set(value) = this.ViewData <- value |
0 commit comments