Search code examples
asp.net-web-apirazorengine

RazorEngine WebApiTemplateBase @Url.Content()


How can I get @Url.Content() working in my _Layout.cshtml when RazorEngine is being used from ASP.NET Web API?

RazorEngine (v.3.7.2) only deals with the Razor syntax and not the additional helper methods like @Html or @Url. These can be added by extending the TemplateBase<> and setting it in the configuration.

There are code examples in some old issues: #26, #29; in an unreleased, incomplete piece of code in MvcTemplateBase.cs; and in the documentation for Extending the Template Syntax.

My problem is I'm using ASP.NET Web API (v.1) which won't have HttpContext.Current (nor should it). I want to provide a UrlHelper as I want to use its Content() method but it needs to be instantiated with the HttpRequestMessage which won't be available.

Perhaps there's no way to get @Url helper methods for my compiled layout. Perhaps I need some other way of getting the absolute path from the virtual path. It seems I'd still need some way of checking the Request though.


Solution

  • A way to get this working is to follow the direction set by Extending the Template Syntax and use VirtualPathUtility.ToAbsolute() in a helper method.

    using System.Web;
    using RazorEngine.Templating;
    
    namespace MyNamespace.Web
    {
        public abstract class WebApiTemplateBase<T> : TemplateBase<T>
        {
            protected WebApiTemplateBase()
            {
                Url = new UrlHelper();
            }
    
            public UrlHelper Url;
        }
    
        public class UrlHelper
        {
            public string Content(string content)
            {
                return VirtualPathUtility.ToAbsolute(content);
            }
        }
    }
    

    Set up the TemplateService configuration with this extension of the TemplateBase<>.

    var config =
        new RazorEngine.Configuration.TemplateServiceConfiguration
        {
            TemplateManager = new TemplateManager(),
            BaseTemplateType = typeof(WebApiTemplateBase<>)
        };