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!
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, ..."