无法解析父控制器的视图

时间:2010-10-21 12:42:08

标签: asp.net-mvc parentviewcontroller

创建一个控制器:

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

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

public class MyController : MyBaseController 
{

}

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

  

视图'MyAction'或其主人   无法找到。下列   搜索地点:   〜/查看/ myController的/ MyAction.aspx   〜/查看/ myController的/ MyAction.ascx   〜/查看/共享/ MyAction.aspx   〜/查看/共享/ MyAction.ascx

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

3 个答案:

答案 0 :(得分: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);
        }
    }

希望这会有所帮助

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

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

如果您的视图是在控制器之间共享的,那么最好将其放在NickLarsen建议的Views/Shared文件夹中。