ASP.NET MVC Tip #24 – Retrieve Views from Different Folders

In this tip, I demonstrate how you can retrieve a view from any folder in an ASP.NET MVC application. I show you how to use both specific paths and relative paths.

Until today, I thought that a controller action could return a view from only one of two places:

· Views\controller name

· Views\Shared

For example, if you are working with the ProductController, then I believed that you could only return a view from either the Views\Product folder or the Views\Shared folder. When looking through the source code for the ViewLocator class, I discovered that I was wrong. If you supply a “Specific Path” for a view, you can retrieve a view from any location in an ASP.NET MVC application.

The ProductController.Index() action in Listing 1 returns a view from the specific path ~\Confusing\ButWorks.aspx.

Listing 1 – ProductController.vb (VB.NET)

Public Class ProductController
    Inherits Controller
 
      Public Function Index() As ActionResult
       Return View("~\Confusing\ButWorks.aspx")
      End Function
End Class

Listing 1 – ProductController.cs (C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace Tip24.Controllers
{
    public class ProductController : Controller
    {
        public ActionResult Index()
        {
            return View( @"~\Confusing\ButWorks.aspx");
        }
    }
}
 

A specific path is a path that starts with either the character ~ or /. Any other path gets treated differently.

You also can use relative paths such as SubProduct\Details or SubProduct/Details. Either relative path will return a view located at Views\Product\SubProduct\Details.aspx. Listing 2 contains a complete code listing that illustrates using relative paths.

Listing 2 – ProductController.vb (VB.NET)

Public Class ProductController
    Inherits Controller
  
      Public Function Index() As ActionResult
       Return View("SubProduct\Details")
      End Function
 
End Class

Listing 2 – ProductController.cs (C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace Tip24.Controllers
{
    public class ProductController : Controller
    {
        public ActionResult Index()
        {
            return View(@"SubProduct\Details");
        }
 
    }
}

Now, I want to be the first to warn you that you should never, never, never use this tip (Please delete this entry from your news aggregator immediately). There is a good reason for following the conventions inherent in an MVC application. Placing your files in known locations makes it easier for everyone to understand your application.

5 Comments

  • Good tip. Agreed on the 'never break this rule' bit. Except I break it. My User, Products, etc controllers all, er, control their own Admin actions rather than making a different AdminUser, AdminProducts, etc controller, so I do sub-folder those views. So rather than having a index.aspx and an admin_index.aspx in the same folder. I have an index.aspx and an admin/index.aspx, and I use View("admin/index") in the admin_index() action. Breaking the rules? Sure, a little, but it's still crystal clear.

  • Hi,

    yesterday I did a post on my Blog in german language to show how to implement a custom viewlocator which only defines another target folder for the views. In my example its '/MVC/Views'.

    Maybe you want to complete your blog post by mentioning this approach.

    Here is my blogpost:

    http://blog.dotnet-expert.de/2008/07/22/ImplementierenEinesEigenenViewLocatorsF%c3%bcrASPNetMVC.aspx

    Greet,
    Jens

  • Thanks for stressing the convention. I think it is really important have this been an extreme case for drifting from the convention.

  • I had to include 'Views' in the path to get this to work:

    @"~\Views\Confusing\ButWorks.aspx"

  • I landed on this post because I'm trying to do what Jens is doing - it would be nice to have a configurable root directory, rather than assuming the root of the web site.

    For example, I am trying to have the MVC run under an /admin/ directory, but nowhere else in the web site.

    Jens' solution actually is pretty good! Thanks for the discussion!

Comments have been disabled for this content.