RazorVirtualPathProvider issue

Mar 16, 2011 at 9:01 PM
Edited Mar 16, 2011 at 9:04 PM

Hi!

I tried to use RazorEngine in my ASP.NET webforms website, but after adding

HostingEnvironment.RegisterVirtualPathProvider(new RazorVirtualPathProvider());

to Application_Start handler my website stops from pages processing: any request to the website ends up with 404 error: "The resource cannot be found".

I made all the necessary changes to my website as described in "Configuring RazorEngine for ASP.NET Medium Trust" section.

Any ideas how to solve this?

Thanks in advance!

Coordinator
Mar 16, 2011 at 9:20 PM
Edited Mar 16, 2011 at 9:23 PM

That's strange, by default if the RazorVirtualPathProvider doesn't handle a request it passes it on. I'll take a look at it - could be a bug! :)

Could you post your config?

Mar 17, 2011 at 11:37 AM

Yep, sure. Here it is:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
    <section name="razorEngine" type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine" requirePermission="false"/>
  </configSections>
  <appSettings configSource="appSettings.config"/>
  <connectionStrings configSource="connectionStrings.config"/>
  <razorEngine factory="RazorEngine.Web.WebCompilerServiceFactory, RazorEngine.Web">
    <!-- Global Namespaces -->
    <namespaces>
      <add namespace="Atcs.Utility"/>
    </namespaces>
    <templateServices default="DefaultTemplateService">
      <add name="DefaultTemplateService">
        <namespaces>
          <add namespace="Atcs.Utility"/>
        </namespaces>
      </add>
    </templateServices>
  </razorEngine>
  <system.web>
    <customErrors mode="Off"/>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>
      <buildProviders>
        <add extension=".csrzr" type="RazorEngine.Web.CSharp.CSharpRazorBuildProvider, RazorEngine.Web"/>
        <add extension=".vbrzr" type="RazorEngine.Web.VisualBasic.VBRazorBuildProvider, RazorEngine.Web"/>
      </buildProviders>
    </compilation>
    <authentication mode="Forms">
      <forms name=".AtcsAuth" loginUrl="login.aspx" timeout="60" protection="All" requireSSL="false" defaultUrl="/default.aspx"/>
    </authentication>
    <roleManager enabled="false"/>
    <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
    <pages theme="Default" validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
    </pages>
    <httpRuntime requestValidationMode="2.0"/>
    <httpHandlers>
      <add verb="*" path="sitemap.axd" type="Newtonsoft.Sitemaps.SitemapHandler, Newtonsoft.Sitemaps"/>
    </httpHandlers>
    <httpModules>
      <add name="AuthenticationModule" type="Atcs.Handlers.AuthenticationModule"/>
    </httpModules>
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>
  <system.runtime.caching>
    <memoryCache>
      <namedCaches>
        <add name="default" cacheMemoryLimitMegabytes="0" physicalMemoryLimitPercentage="0" pollingInterval="00:02:00"/>
      </namedCaches>
    </memoryCache>
  </system.runtime.caching>
  <!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="AuthenticationModule" type="Atcs.Handlers.AuthenticationModule" preCondition="managedHandler"/>
    </modules>
    <handlers>
      <add name="ImageHandler" verb="GET" path="Image.ashx" type="Atcs.Handlers.ImageHandler" preCondition="managedHandler"/>
      <add name="ExportServeRequestsHandler" verb="GET" path="Admin/Requests/Export.ashx" type="Atcs.Handlers.ExportServeRequestsHandler" preCondition="managedHandler"/>
      <add name="SitemapHandler" verb="GET" path="sitemap.xml" type="Newtonsoft.Sitemaps.SitemapHandler, Newtonsoft.Sitemaps"/>
    </handlers>
  </system.webServer>
  <log4net>
    <appender name="WebsiteAppender" type="log4net.Appender.RollingFileAppender">
      <file value="App_Data\Logs\Website\Website.log"/>
      <appendToFile value="true"/>
      <rollingStyle value="Date"/>
      <datePattern value="yyyyMMdd"/>
      <lockingModel value="log4net.Appender.FileAppender.MinimalLock"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
      </layout>
    </appender>
    <appender name="ServiceAppender" type="log4net.Appender.RollingFileAppender">
      <file value="App_Data\Logs\Service\Service.log"/>
      <appendToFile value="true"/>
      <rollingStyle value="Date"/>
      <datePattern value="yyyyMMdd"/>
      <lockingModel value="log4net.Appender.FileAppender.MinimalLock"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
      </layout>
    </appender>
    <logger name="Website">
      <appender-ref ref="WebsiteAppender"/>
      <level value="All"/>
    </logger>
    <logger name="Service">
      <appender-ref ref="ServiceAppender"/>
      <level value="All"/>
    </logger>
  </log4net>
</configuration>

Mar 17, 2011 at 1:28 PM

Good news from me - just got it work!

I created a new virtual path provider by inheriting from yours RazorEngine.Web.RazorVirtualPathProvider and overrided FileExists method:

    public class MyVirtualPathProvider : RazorEngine.Web.RazorVirtualPathProvider
    {
        public override bool FileExists(string virtualPath)
        {
            return Previous.FileExists(virtualPath) || base.FileExists(virtualPath);
        }
    }

MSDN says that Previous property gets a reference to a previously registered VirtualPathProvider object in the compilation system.

After this it works like a charm!

Coordinator
Mar 17, 2011 at 3:15 PM

Awesome. I'm going to have to look at that method as I wasn't aware of it's existence. I've written 3 different VPPs and haven't had an issue. :)