Custom ViewEngine problem with ASP.NET MVC

Posted by mare on Stack Overflow See other posts from Stack Overflow or by mare
Published on 2010-03-21T15:50:14Z Indexed on 2010/03/21 19:11 UTC
Read the original article Hit count: 592

Filed under:

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().

© Stack Overflow or respective owner

Related posts about asp.net-mvc