How to determine if a view exists in ASP.NET MVC 3?

I am introducing a new ASP.NET MVC 3 application that will use the dynamic routing form to determine which view is returned from the general controller action. I would like the view to display by default if there is no view in the dynamic location.

Think of it as navigating a tree structure. There is only one TreeController in the Controllers root folder. It has a browse action method that takes the node path to view. Each node can have a custom look, so I need to first try to find this view and return it from the action method, for example:

public ViewResult Browse(String path) { var model = ...; return View(path, model); } 

So, if I go to "MySite / Tree / A / B / C", I would expect to find the view in "\ Views \ Tree \ A \ B \ C.aspx".

However, if there is no custom view, I need to refer to the standard default views (for example, "\ Views \ Tree \ Browse.aspx").

Since this applies only to this action method, I do not believe that I should handle NotFound errors that may arise due to other circumstances. And I'm not looking for dynamic routing, as described in other posts, because the path to the controller is fixed.

+4
source share
2 answers

Controllers do not need to know about physical representations.

You do this by creating a custom view engine, for example:

 public class MyViewEngine: WebFormViewEngine { public MyViewEngine() { ViewLocationFormats = ViewLocationFormats.Concat( new [] {"~/Views/{1}/Browse.aspx""}).ToArray(); // similarly for AreaViewLocationFormats, etc., if needed } } 

For more information, see the source code, for example, WebFormViewEngine.

If you need to do this conditionally (only for a few actions), you can override FindView in this type and look at the route values.

Obviously if you are using Razor then change it instead.

Then in Global.asax.cs use it:

 private void Application_Start(object sender, EventArgs e) { // stuff ViewEngines.Engines.Add(new MyViewEngine()); 
+1
source

Inside the controller action, this works:

 var fullPath = string.Format("~/Views/CustomStuff/{0}.cshtml", viewname); var mappedPath = Server.MapPath(fullPath); if( !System.IO.File.Exists(mappedPath) ) return View("Default"); else return View(viewname); 

(note: not precompilation)

+1
source

All Articles