In the method FindView() I have to somehow check if the View we are requesting is a ViewUserControl. Because otherwise I get an error saying:
"A master name cannot be specified when the view is a ViewUserControl."
This is my custom view engine code right now:
public class PendingViewEngine : VirtualPathProviderViewEngine
{
public PendingViewEngine()
{
// This is where we tell MVC where to look for our files.
/* {0} = view name or master page name
* {1} = controller name */
MasterLocationFormats = new[] {"~/Views/Shared/{0}.master", "~/Views/{0}.master"};
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx", "~/Views/Shared/{0}.ascx",
"~/Views/{1}/{0}.ascx"
};
PartialViewLocationFormats = new[] {"~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx"};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new WebFormView(partialPath, "");
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new WebFormView(viewPath, masterPath); // this line produces the error because we cannot set master page on ASCXs, so I need an "if" here
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
if (controllerContext.HttpContext.Request.IsAjaxRequest())
return base.FindView(controllerContext, viewName, "Modal", useCache);
return base.FindView(controllerContext, viewName, "Site", useCache);
}
}
The above ViewEngine fails on calls like this:
<% Html.RenderAction("Display", "MyController", new { zoneslug = "some-zone-slug" });%>
The action I am rendering here is this:
public ActionResult Display(string zoneslug)
{
WidgetZone zone;
if (!_repository.IsUniqueSlug(zoneslug))
zone = (WidgetZone) _repository.GetInstance(zoneslug);
else
{
// do something here
}
// WidgetZone used here is WidgetZone.ascx, so a partial
return View("WidgetZone", zone);
}
I cannot use RenderPartial because you cannot send route values to RenderPartial the way you can to RenderAction. To my knowledge there is no way to provide RouteValueDictionary to RenderPartial() like the way you can to RenderAction().