Question

Microsoft has a new website editing tool: WebMatrix. WebMatrix uses the new Web Pages engine in which Razor is the view engine; Razor is also the new view engine for MVC3. I am attempting to find out if it is possible to register and use a different view engine in Web Pages (like you can in MVC).

Does anyone know if it is possible to add or replace the view engine in Web Pages? If so has anyone documented this? Examples?

Was it helpful?

Solution

I'm hoping to try this myself a bit later, but for now I'll just share my current thoughts:

In WebPages, Razor works by registering a BuildProvider with the ASP.NET build pipe for .cshtml and .vbhtml.

WebPages, in turn, registers the .cshtml .vbhtml extensions to its handler.

When a webPages page is requested, System.Web.WebPages.WebPageHttpHandler passes the path to the build pipe, where the extensions are matched with the registered Razor Provider, which renders the page and passes back a WebPage object, which handler passes to IIS and is served up.

You'll see all this if you use a reflection tool. Both of these are achieved in the PreApplicationStartCode.Start() of the corresponding assembly.

Razor hooking its build provider:

public static void Start()
{
    if (!_startWasCalled)
    {
        _startWasCalled = true;
        BuildProvider.RegisterBuildProvider(".cshtml", typeof(RazorBuildProvider));
        BuildProvider.RegisterBuildProvider(".vbhtml", typeof(RazorBuildProvider));
    }
}

WebPages hooking the WebPageHandler

public static void Start()
{
    if (!_startWasCalled)
    {
        _startWasCalled = true;
        WebPageHttpHandler.RegisterExtension("cshtml");
        WebPageHttpHandler.RegisterExtension("vbhtml");
        PageParser.EnableLongStringsAsResources = false;
        DynamicModuleUtility.RegisterModule(typeof(WebPageHttpModule));
        ScopeStorage.CurrentProvider = new AspNetRequestScopeStorageProvider();
    }
}

To override we'd need to create and register a separate BuildProvider with the ASP.NET pipe to render our pages. System.Web.WebPages provides a WebPageHttpHandler.RegisterExtension() method which in theory you can hook a different BuildProvider to which will get the WebPage request instead of Razor.

Several blogs mention the RegisterExtension method, but there is also an open connect bug report showing it doesn't work 100%. It may be more appropriate to just override everything and hook our buildprovider to the pipe (not using the method).

Web.config provides a construct to register buildProviders, so I'll prob try that.

<buildProviders>
   <add extension=".cshtml" type="CustomStuff.CustomBuildProvider"/>
</buildProviders>

The challenge is that most of the view engines out there use ViewEngines.Register(), a concept that webPages does not appear to have. So we'd have to wrap those view engines in a BuildProvider and/or create a BuildProvider that can successfully invoke IViewEngine

Again, just sharing my thinking. I'll try to register Spark or something later if I find some time.

OTHER TIPS

You can't "register" view engines in Web Pages in the same way as MVC. You just mix and match file types. There's nothing to stop you adding .aspx files to your Web Pages site. Web Pages is much more akin to a Web Site project in VS.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top