开发者

Cannot resolve view of the parent controller

开发者 https://www.devze.com 2023-01-21 06:49 出处:网络
Create a controller: public abstract class MyBaseController : Controller { public ActionResult MyAction(string id)

Create a controller:

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

Than create another specific controller that inherit from MyBaseController:

public class MyController : MyBaseController 
{

}

There is a view called MyAction.aspx in the Views/MyBaseController folder Then, call MyController/MyAction method. Following exception will be generated:

The view 'MyAction' or its master could not be found. The following locations were searched: ~/Views/MyController/MyAction.aspx ~/Views/MyController/MyAction.ascx ~/Views/Shared/MyAction.aspx ~/Views/Shared/MyAction.ascx

Can I make MVC.NET to use the view from Views/MyBaseController fol开发者_C百科der?


you should wait for a more finesse answer but this work:

Create a new view engine based on the default one and override the FindViewMethod this way:


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

Add the new view engine:


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

hope this helps


You need to add it to shared because you are in the context of the subcontroller. If you want different behavior for different controllers, then you'll want to put a MyAction view in each of your subcontroller view folders.

To answer your question though, you probably could make it look in base controller folder, but it would require you to write your own request handler which looks in base controller folders. The default implementation only looks in the view folder for the current controller context, then it looks in the shared folder. It sounds like your view is shared however, so the shared folder seems like a good place for it anyway.


It is possible, but not very clean.

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

However if your View (MyAction.aspx) contains a reference to a Partial View, ASP.NET MVC will look for it in the Views/MyController folder (and not find it there!).

If your view is shared across controllers, its best to place it in the Views/Shared folder as recommended by NickLarsen.

0

精彩评论

暂无评论...
验证码 换一张
取 消