1

So, I personally think this is sort of whack.

I put a .aspx template in a nonstandard location. In this example, it has a virtual path of ~/Content/Sites/magical/Index.aspx.

I then created my own view engine as a test, which extends WebFormsViewEngine:


public class MagicalWebFormsViewEngine : WebFormViewEngine
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        string viewTemplatePath = "~/Content/Sites/magical/" + viewName + ".aspx";
        string masterTemplatePath = string.Empty;
        return new ViewEngineResult(
            this.CreateView(controllerContext, viewTemplatePath, masterTemplatePath),
            this
        );
    }
}

The template looks like this:


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Plain.Master" Inherits="System.Web.Mvc.ViewPage<MySoln.Client.Presentation.MyPresenter>" %>
...
<%: Model.SomePresenterSpecificMember %>

If I leave the strongly-typed declaration in the Inherits attribute of the Page declaration, I get the following exception:

Parser Error Message: Could not load type 'System.Web.Mvc.ViewPage<MySoln.Client.Presentation.MyPresenter>'.

However, if I change the template to use a weakly-typed page model, and instead use a cast on the Model member in the template itself, it works:


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Plain.Master" Inherits="System.Web.Mvc.ViewPage" %>
...
<% var omg = (MySoln.Client.Presentation.MyPresenter) Model; %>
<%: omg.SomePresenterSpecificMember %>

So, my question is, why does the former barf and the latter work? I'd rather not cast Model to one of my presenter types in a tag at the top of every template.

Thanks!

  • I'd double & triple check, that looks like the standard error where 'MySoln.Client.Presentation.MyPresenter' isn't right. Also when you do the later, have you run it to make sure it doesn't fail when running? – eglasius Sep 17 '10 at 17:46
  • I double checked the declaration in inherits, still the same problem. And yes, I've actually run the latter to make sure it renders correctly. Thanks for the suggestions! – Michael DiBernardo Sep 17 '10 at 17:51

1 Answers1

1

Just make sure that you have the following web.config file at the root of your custom view engine path:

<?xml version="1.0"?>

<configuration>
  <system.web>
    <httpHandlers>
      <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
    </httpHandlers>

    <!--
        Enabling request validation in view pages would cause validation to occur
        after the input has already been processed by the controller. By default
        MVC performs request validation before a controller processes the input.
        To change this behavior apply the ValidateInputAttribute to a
        controller or action.
    -->
    <pages
        validateRequest="false"
        pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
      </controls>
    </pages>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />

    <handlers>
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
</configuration>

You could copy-paste the web.config file automatically generated by the default template and located in ~/views/web.config into ~/content/web.config.

Basically the important part is :

pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, ..."

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • So, does this mean that any virtual directory tree that contains templates must have this kludgy web.config in its root folder? Out of curiousity, is this behaviour documented somewhere? I'd like to read the reasoning behind it, etc. Thanks again! – Michael DiBernardo Sep 17 '10 at 18:04
  • @Michael, it's the `pageBaseType` attribute that matters which instructs the ASP.NET compiler of the base type. – Darin Dimitrov Sep 17 '10 at 18:05