1

创建控制器:

public abstract class MyBaseController : Controller
{
   public ActionResult MyAction(string id)
   {
      return View();
   }
}

比创建另一个从 MyBaseController 继承的特定控制器:

public class MyController : MyBaseController 
{

}

在 Views/MyBaseController 文件夹中有一个名为 MyAction.aspx 的视图然后,调用 MyController/MyAction 方法。将产生以下异常:

找不到视图“MyAction”或其主视图。搜索了以下位置: ~/Views/MyController/MyAction.aspx ~/Views/MyController/MyAction.ascx ~/Views/Shared/MyAction.aspx ~/Views/Shared/MyAction.ascx

我可以让 MVC.NET 使用 Views/MyBaseController 文件夹中的视图吗?

4

3 回答 3

3

您应该等待更巧妙的答案,但这项工作:

创建一个基于默认视图引擎的新视图引擎,并以这种方式覆盖 FindViewMethod:


 public class MyNewViewEngine : WebFormViewEngine
 {
     public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
     {
        var type = controllerContext.Controller.GetType();

            //Retrieve all the applicable views.
            var applicableViews = from m in type.GetMethods()
                                  where typeof(ActionResult).IsAssignableFrom(m.ReturnType) & m.Name == viewName
                                  select m;

            //Save the original location formats.
            var cacheLocations = ViewLocationFormats;
            var tempLocations = cacheLocations.ToList();

            //Iterate over applicable views and check if they have been declared in the given controller.
            foreach(var view in applicableViews)
            {
                //If not, add a new format location to the ones at the default engine.
                if (view.DeclaringType != type)
                {
                    var newLocation = "~/Views/" + view.DeclaringType.Name.Substring(0, view.DeclaringType.Name.LastIndexOf("Controller")) + "/{0}.aspx";
                    if (!tempLocations.Contains(newLocation))
                        tempLocations.Add(newLocation);
                }
            }

            //Change the location formats.
            ViewLocationFormats = tempLocations.ToArray();

            //Redirected to the default implementation
            var result = base.FindView(controllerContext, viewName, masterName, useCache);

            //Restore the location formats
            ViewLocationFormats = cacheLocations;

            return result;
   }
}

添加新的视图引擎:


 public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new MyNewViewEngine());
            RegisterRoutes(RouteTable.Routes);
        }
    }

希望这可以帮助

于 2010-10-21T13:42:11.287 回答
0

您需要将其添加到 shared 因为您在子控制器的上下文中。如果您想要不同控制器的不同行为,那么您需要在每个子控制器视图文件夹中放置一个 MyAction 视图。

不过,要回答您的问题,您可能可以让它在基本控制器文件夹中查找,但这需要您编写自己的请求处理程序,该处理程序在基本控制器文件夹中查找。默认实现仅在视图文件夹中查找当前控制器上下文,然后在共享文件夹中查找。但是,听起来您的视图是共享的,因此无论如何共享文件夹似乎都是一个好地方。

于 2010-10-21T12:46:20.210 回答
0

这是可能的,但不是很干净。

public class MyController : MyBaseController 
{
   public ActionResult MyAction(string id)
   {
       return View("~/Views/MyBaseController/MyAction.aspx");
   }
}

但是,如果您的 View (MyAction.aspx) 包含对 Partial View 的引用,ASP.NET MVC 将在 Views/MyController 文件夹中查找它(而不是在那里找到它!)。

如果您的视图是跨控制器共享的,最好将它放在Views/SharedNickLarsen 推荐的文件夹中。

于 2010-10-21T13:08:24.770 回答