Custom ViewEngine problem with ASP.NET MVC
- by mare
In this question jfar answered with his solution the problem is it does not work for me. 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);
}
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", "WidgetZoneV2", new { zoneslug = "left-default-zone" }); %>
As you can see, I am providing Route values to my RenderAction call.
The action I am rendering here is this:
// Widget zone name is unique
// GET: /WidgetZoneV2/{zoneslug}
public ActionResult Display(string zoneslug)
{
zoneslug = Utility.RemoveIllegalCharacters(zoneslug);
// Displaying widget zone creates new widget zone if it does not exist yet; so it prepares our page for
// dropping of content widgets
WidgetZone zone;
if (!_repository.IsUniqueSlug(zoneslug))
zone = (WidgetZone) _repository.GetInstance(zoneslug);
else
{
// replace slug with spaces to convert it into Title
zone = new WidgetZone {Slug = zoneslug, Title = zoneslug.Replace('-', ' '), WidgetsList = new ContentList()};
_repository.Insert(zone);
}
ViewData["ContentItemsList"] = _repository.GetContentItems();
return View("WidgetZoneV2", zone);
}
I cannot use RenderPartial (at least I don't know how) the way I can RenderAction. To my knowledge there is no way to provide RouteValueDictionary to RenderPartial() like the way you can to RenderAction().