U4-3224 - Updated UmbracoViewPage to check the model type and cast/convert/change accordingly based on the given model

Created by Shannon Deminick 23 Oct 2013, 22:17:41 Updated by Stephan 06 Mar 2014, 07:23:56

This is a continuation from this discussion here: http://our.umbraco.org/projects/developer-tools/umbraco-codegen/development-discussion/45586-2013-10-20-Road-ahead

Essentially this will solve the following problems/features:

  • We want to use IPublishedContent as Model on a view (not RenderModel)
  • We want to be able to use a strongly typed implementation of IPublishedContent on our view such as UmbracoViewPage
  • We want to be able to change the default generic view type in the ~/Views/web.config so we can just decare @model instead of @inherits
  • We don't want to have to change the current default MVC controller to achieve all of this and we want these changes to be 100% backwards compatible

To do this should be quite easy:

  • Override SetViewData on UmbracoViewPage
  • viewData.Model.TryConvertTo() - this will work if viewData.Model is already T or if there is a type converter registered for this conversion ** We will implement a custom TypeConverter for RenderModel to be able to automatically convert to IPublishedContent so the above will always work when viewData.Model is RenderModel and T is IPublishedContent
  • If that fails, check if T implements IPublishedContent ** If so then execute viewData.Model.TryConvertTo() ** This will work because of our TypeConverter which will return the IPublishedContent implementation from the model factory which will/should = T
  • Then set viewData.Model = converted

This gives us some pretty huge flexibility with UmbracoViewPage


Stephan 24 Oct 2013, 07:37:26

Have a prototype running for that one... stay tuned...

Stephan 24 Oct 2013, 19:33:05

Have it working, now documenting, will push (hopefully) tomorrow.

Stephan 25 Oct 2013, 11:16:02

Pushing commit onto 6.2.0 soon. So now you can use any of these:

@inherit UmbracoViewPage :: Model is IPublishedContent @inherit UmbracoViewPage :: Model is MyContentType @inherit UmbracoViewPage :: Model is MyModel @inherit UmbracoTemplatePage :: Model is RenderModel, Model.Content is IPublishedContent @inherit UmbracoTemplatePage :: Model is RenderModel, Model.Content is MyContentType

Looks like we don't need type converters, UmbracoViewPage does all the conversions between IPublishedContent, strongly-typed content, RenderModel, etc... by itself. With that in place, I don't see why anybody would still use UmbracoTemplatePage but it's there for backward compatibility. I assume that with this in place, every template or partial view is going to inherit from UmbracoViewPage one way or another.

When doing @Html.Partial(...) you can pass pretty much anything as a model, ie an IPublishedContent, a strongly-yped content, a RenderModel... and the view will re-map that to the expected model, provided it is possible of course.

If you change the view type in Web.config to UmbracoViewPage, all you need to do is one of these:

@model IPublishedContent @model MyContentType @model MyModel

NOTE: if you don't indicate neither @inherits nor @model then the view will be of type WebViewPage, or UmbracoViewPage if you've changed the type in Web.config. It can't be of type UmbracoViewPage (non-generic) by default.

When inheriting from UmbracoViewPage, if MyModel implements IRenderModel, then the UmbracoHelper will be initialized with Model.Content, so that @Umbraco.Field("myProperty") works properly. So if your model contains, say, a main content to render and some other stuff, you can expose the content easily and the UmbracoHelper will use it. Otherwise, the UmbracoHelper uses the default content, which is the current PublishedContentRequest content.

It should be all backward-compatible. It works with the default controller which is unchanged. Can ppl review the code, and comment?

NOTE: I'd like things to be as simple with partial view macros... will look into how they work soon as I have some time.

Stephan 25 Oct 2013, 12:08:45

And that would be commit 128a08f.

Shannon Deminick 27 Oct 2013, 23:50:32

Looks pretty awesome to me!

Lars-Erik Aabech 28 Oct 2013, 20:50:46

Looks great. Sorry I haven't been able to give it a whirl yet. Hope to squeeze in time real soon. Will let you know. I'm sure it'll be a breeze.

Jesper Haug Karsrud 31 Oct 2013, 14:39:28

This stuff looks pretty solid now, can't wait to try this out properly in an actual release!

Shannon Deminick 06 Mar 2014, 01:31:13

Stephen, can you mark this as fixed if it is complete?

Stephan 06 Mar 2014, 07:23:47

Status: looks OK to me, using it on a 6.2 website and it works as intended. Closing.

Priority: Normal

Type: Task

State: Fixed


Difficulty: Normal

Category: Architecture

Backwards Compatible: True

Fix Submitted:

Affected versions:

Due in version: 7.1.0, 6.2.0


Story Points: