如何确定ASP.NET MVC 3中是否存在View?

时间:2011-07-22 12:42:18

标签: asp.net-mvc-3

我正在实现一个新的ASP.NET MVC 3应用程序,它将使用一种动态路由形式来确定从公共控制器操作返回的视图。如果动态位置没有视图,我希望显示一个默认视图。

将其想象为导航树结构。根控制器文件夹中只有一个TreeController。它有一个Browse动作方法,它接受要浏览的节点的路径。每个节点都可以有一个自定义视图,所以我需要首先尝试找到该视图并从action方法返回它,如下所示:

public ViewResult Browse(String path)
{
    var model = ...;

    return View(path, model);
}

所以,如果我导航到“MySite / Tree / A / B / C”,那么我希望在“\ Views \ Tree \ A \ B \ C.aspx”中找到一个视图。

但是,如果没有自定义视图,我需要遵循标准/默认视图(例如“\ Views \ Tree \ Browse.aspx”)。

由于这只是这个动作方法的情况,我不相信我应该处理因其他情况可能导致的NotFound错误。并且,我不是在寻找其他帖子中描述的动态路由,因为控制器的路径是固定的。

2 个答案:

答案 0 :(得分:1)

控制者不应该了解物理视图。

您可以通过编写自定义视图引擎来完成此操作,例如:

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

有关详细信息,请参阅WebFormViewEngine的源代码。

如果您需要有条件地执行此操作(仅执行少量操作),则可以覆盖该类型中的FindView并查看路由值。

显然,如果你使用Razor,那就改变那个。

然后,在Global.asax.cs中,使用它:

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

答案 1 :(得分:0)

在Controller操作中,这似乎有效:

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);

(注意:不预编译视图)