Block template selection when using a controller


Another question for you guys!

Say I have defined a NewsBlock which has its own NewsBlockController. This controller fetches some pages, does some logic etc and maps the data to a simple view model, NewsViewModel, which is rendered in a Views/NewsBlock/Index.cshtml (typed to NewsViewModel). This works fine, everything as expected.

Now, on some pages (where I have the NewsBlock as a local property), I would like render the block slightly different, using another template. All I want to do is to trigger the use of another .cshtml-file (but still go via the same controller and view model). I thought I could solve this by introducing a tag like this:

@Html.PropertyFor(m => m.NewsBlock, new { Tag = "Condensed" })

and register another template (I'm using the TemplateCoordinator class as in the Alloy project) something like this:


viewTemplateModelRegistrator.Add(typeof(NewsBlock), new TemplateModel
Name = "NewsCondensed,
Inherited = true,
Tags = new[] { "Condensed" },
AvailableWithoutTag = false,
Path = "~/Views/NewsBlock/Condensed.cshtml"

But obviously, this isn't quite right! First of all, if I trigger this specific template (by using the "Condensed" tag), it wouldn't involve the NewsBlockController, it goes directly for partial view. Secondly, the Condensed.cshtml expects a NewsViewModel, not a NewsBlock type (resulting in an exception).

Any suggestions how to solve this? Do I need to duplicate the controller (and decorate it with another tag using the TemplateDescriptor attribute)? :/ 




Feb 05, 2014 16:27

In a block controller you can get the view data from the "main" view (a block controller is called through a child action call). So you could have a view like eg:

@Html.PropertyFor(m => m.CurrentPage.MyBlock, new { View = "Condensed" })

then in the block controller you could check if the parent context has a value for the property (View in this case) as:

 public override ActionResult Index(TestBlock currentBlock)
            var parentContext = this.RouteData.DataTokens["ParentActionViewContext"] as ViewContext;
            if (parentContext != null)
                var viewName = parentContext.ViewData["View"] as string;
                if (!String.IsNullOrEmpty(viewName))
                    return PartialView(viewName, currentBlock);

            return PartialView(currentBlock);


Feb 06, 2014 9:50


Yes, I figured I could pass the viewdata myself. I was hoping for a more "built-in" way of doing it, but this will be good enough!

Feb 06, 2014 11:31
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.