Changing base view type on MVC4

Halil Ibrahim picture Halil Ibrahim · Jan 16, 2013 · Viewed 14.8k times · Source

I've read a post about changing base view type on MVC from the link below:

http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx

I followed the instructions but my page still inherits from System.Web.Mvc.WebViewPage. I can't reach any property defined in my custom view base and I get an error on runtime. When I use @inherits keyword, it fixes.

Web.config

<pages pageBaseType="[MyNamespace].WebViewPageBase">
  <namespaces>
    <add namespace="System.Web.Helpers" />
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization" />
    <add namespace="System.Web.Routing" />
    <add namespace="System.Web.WebPages" />
  </namespaces>
</pages>

WebViewPageBase

public class WebViewPageBase : WebViewPage
{
    public SomeType MyProperty { get; set; }

    public override void InitHelpers()
    {
        base.InitHelpers();
        MyProperty = { foo };
    }

    public override void Execute()
    {

    }
}


public class WebViewPageBase<T> : WebViewPage<T>
{
    public SomeType MyProperty { get; set; }

    public override void InitHelpers()
    {
        base.InitHelpers();
        MyProperty = { foo };
    }

    public override void Execute()
    {

    }
}

Partial View

@model TopMenuModel

<div class="topMenu">
@MyProperty
</div>

But in the post I've read there is no instruction about @inherits keyword. Is there any thing that I miss or any way to make this work without @inherits keyword in all pages?

SOLVED:

web.config file in root directory is not the right one. I changed base type in the web.config file under View directory and it fixed.

Answer

Darin Dimitrov picture Darin Dimitrov · Jan 16, 2013

Why did you show two versions of WebViewPageBase: generic and non-generic?

You only need the generic version:

public class MyWebView<T> : WebViewPage<T>
{
    public SomeType MyProperty { get; set; }

    public override void InitHelpers()
    {
        base.InitHelpers();
        MyProperty = new SomeType();
    }

    public override void Execute()
    {
    }
}

and then:

<pages pageBaseType="MvcApplication1.WebViews.MyWebView">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
  </namespaces>
</pages>

Now inside your views you will be able to use the property:

@model TopMenuModel

<div class="topMenu">
    @MyProperty
</div>

UPDATE:

Step by step setup:

  1. Create a new ASP.NET MVC 3 application using the Internet Template
  2. Add a custom base view:

    namespace MvcApplication1
    {
        public class MyWebView<T> : WebViewPage<T>
        {
            public string MyProperty { get; set; }
    
            public override void InitHelpers()
            {
                base.InitHelpers();
                MyProperty = "Hello World";
            }
    
            public override void Execute()
            {
            }
        }
    }
    
  3. Set the pageBaseType attribute in ~/Views/web.config (not to be confused with ~/web.config):

    <pages pageBaseType="MvcApplication1.MyWebView">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
    
  4. Inside ~/Views/Home/Index.cshtml use the property:

    <div>
        @MyProperty
    </div>
    
  5. Hit Ctrl+F5 to run the application and if everything goes well you will be greeted with a Hello World.