我正在实现一个新的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错误。并且,我不是在寻找其他帖子中描述的动态路由,因为控制器的路径是固定的。
答案 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);
(注意:不预编译视图)