Antaris / RazorEngine

Open source templating engine based on Microsoft's Razor parsing engine
http://antaris.github.io/RazorEngine
Other
2.14k stars 577 forks source link

TemplateBase missing Context fields #476

Open adriangodong opened 7 years ago

adriangodong commented 7 years ago

RazorEngine.Templating.TemplateBase and RazorEngine.Templating.TemplateBase<T> are missing BeginContext, EndContext, and Context members. These members are called from aspnet_compiler generated view classes.

I propose we add empty/fake members that will resolve the compiler errors and make working with RazorEngine more seamless. I'm not sure how widespread or common this issue is, I welcome any feedback if there's a simpler workaround. I'm willing to work on a PR to resolve this if there's a consensus.

Rationale and Usage

Compiling views using MvcBuildViews msbuild task is a crucial step to avoid JIT view compilation errors. The task will run aspnet_compiler on every build. The compiler does not have a way to whitelist / blacklist folders. This means aspnet_compiler will transform Razor templates into C# classes for all .cshtml files in the project, including those inherited from RazorEngine.Templating.TemplateBase.

Here's a sample of aspnet_compiler-generated C# class that fails build:

namespace ASP {

    public class _Page_EmailTemplates_Templates__EmailLayout_cshtml : RazorEngine.Templating.TemplateBase {

        public _Page_EmailTemplates_Templates__EmailLayout_cshtml() {
        }

        protected ASP.global_asax ApplicationInstance {
            get {
                return ((ASP.global_asax)(Context.ApplicationInstance)); // <-- compile error
            }
        }

        public override void Execute() {
            BeginContext("~/EmailTemplates/Templates/_EmailLayout.cshtml", 144, 15, false); // <-- compile error
            ...
            EndContext("~/EmailTemplates/Templates/_EmailLayout.cshtml", 144, 15, false); // <-- compile error
        }

        ...
    }
}

Adding the members used by the generated class will allow RazorEngine-consumed Razor templates to sit side-by-side with ASP.NET MVC Razor templates and allow MvcBuildViews task to run without any issue.

Proposed API

Add the following members to TemplateBase and TemplateBase<T>:

protected void BeginContext(
    string virtualPath,
    int startPosition,
    int length,
    bool isLiteral)
{
}

protected void EndContext(
    string virtualPath,
    int startPosition,
    int length,
    bool isLiteral
)
{
}

protected Fake Context { get; set; }

public class Fake
{
    public object ApplicationInstance { get; set; }
}

Workarounds

To avoid this issue without changing RazorEngine code, there are several workarounds:

disalinas commented 6 years ago

Hello. We have same problem with some views in a MVC project. Finally we move out views from this project, but we have another problems with this action. In a future these fake methods will be available?

BeniFreitag commented 5 years ago

Thanks @adriangodong. My Workaround was to create another class extending TemplateBase and inherit from that in all affected cshtml-files:

public class MyRazorTemplate<T> : RazorEngine.Templating.TemplateBase<T>
{
    protected void BeginContext(string virtualPath, int startPosition, int length, bool isLiteral) { }

    protected void EndContext(string virtualPath, int startPosition, int length, bool isLiteral) { }

    protected Fake Context { get; set; }

    public class Fake
    {
        public object ApplicationInstance { get; set; }
    }
}