Native MVC support in Umbraco coming very soon!
Its been a while since writing a blog post! … but that’s only because I can never find the time since I’m still gallivanting around the globe :P
But this post is about something very exciting, and I’m sure most of you that are reading this already know that with the upcoming Umbraco 4.10.0 release (currently in Beta and downloadable here) we are natively supporting ASP.Net MVC! What’s more is that I’ve tried to document as much as I could on our GitHub docs. Once my pull request is completed the docs will all be available on the main site but until then you can see them on my fork here.
So where to begin? Well, I’m going to try to keep this really short and sweet because I’m hoping you can find most of the info that you’ll want in the documentation.
What is supported?
Everything that you can do in MVC you will be able to do in Umbraco’s MVC implementation. Anything from Partial Views, Child Actions, form submissions, data annotations, client validation to Surface Controllers, custom routes and hijacking Umbraco routes. If you have used Razor macros before, we support a very similar syntax but it is not 100% the same. We support most of the dynamic querying that you use in Razor macros with the same syntax but to access the dynamic model is slightly different. What is crazy awesome super cool though is that we support a strongly typed query structure!! :) So yes, you can do strongly typed Linq queries with intellisense, no problemo!
Still using Web forms? not a problem, you can have both Web forms and MVC engines running in tandem on your Umbraco site. However, a config setting will set a default rendering engine which will determine whether Web forms master pages or MVC views are created in the back office.
What is not supported (yet)
There’s a few things in this release that we’ve had to push to 4.11.0 due to time constraints. They include: Better tooling support for the View editors in the back office, Partial View Macros and Child Action Macros. Though once you start using this MVC version you’ll quickly discover that the need for macros is pretty small. Perhaps people use macros in different ways but for the most part with the way that MVC works I would probably only use macros for rendering macro content in the WYSIWYG editor.
We support rendering any macros in MVC so you can even render your XSLT macros in your views, but issues will arise if you have User Control or Web form control macros that contain form elements. You will still be able to render these macros but any post backs will not work, and will most likely cause a YSOD. Unfortunately due to the vast differences between how Web forms and MVC work in ASP.Net this is something that we cannot support. The good news is that creating forms in MVC is super easy and makes a whole lot more sense than Web forms…. you can even have more than one <form> element on a page, who’d have thought :P
Strongly typed queries
You can find the documentation for this here but I just wanted to point out some of the differences between the strongly typed syntax and the dynamic syntax. First, in your view you have two properties:
- @Model.Content = the strongly typed model for your Umbraco view which is of type: Umbraco.Core.Models.IPublishedContent
- @CurrentPage = the dynamic model representing the current page, this is very very similar to the @Model property in Razor macros
An example is to get the current page’s children that are visible, here’s the syntax for both (and of course since the @CurrentPage is dynamic, you will not get intellisense):
//dynamic access
@CurrentPage.Children.Where("Visible")
//strongly typed access
@Model.Content.Children.Where(x => x.IsVisible())
There are also some queries that are just not (yet) possible in the dynamic query structure. In order to get some complex queries to work with dynamic linq, we need to code these in to the parser to create the expression tree. The parser could probably do with more TLC to support things like this but IMHO, we’re just better off using the strongly typed way instead (plus its probably a much faster execution). I’ve listed this as an example in the docs but will use it here again:
//This example gets the top level ancestor for the current node, and then gets
//the first node found that contains "1173" in the array of comma delimited
//values found in a property called 'selectedNodes'.
//NOTE: This is one of the edge cases where this doesn't work with dynamic execution but the
//syntax has been listed here to show you that its much easier to use the strongly typed query
//instead
//dynamic access
var paramVals = new Dictionary<string, object> {{"splitTerm", new char[] {','}}, {"searchId", "1173"}};
var result = @CurrentPage.Ancestors().OrderBy("level")
.Single()
.Descendants()
.Where("selectedNodes != null && selectedNodes != String.Empty && selectedNodes.Split(splitTerm).Contains(searchId)", paramVals)
.FirstOrDefault();
//strongly typed
var result = @Model.Content.Ancestors().OrderBy(x => x.Level)
.Single()
.Descendants()
.FirstOrDefault(x => x.GetPropertyValue("selectedNodes", "").Split(',').Contains("1173"));
IMHO i much prefer the strongly typed syntax but it’s up to you to decide since we support both structures.
UmbracoHelper
Another class we’ve introduced is called the Umbraco.Web.UmbracoHelper which is accessible on your views by using the @Umbraco syntax and is also accessible on any SurfaceController. This class contains a ton of handy methods, it is basically the ‘new’ Umbraco ‘library’ class (you know that static one that has a lower case ‘l’ :P ) Of course the ‘library’ class will still be around and you can still use it in your views… but you shouldn’t! This new helper class should contain all of the methods that you need from querying content/media by ids, rendering macros and rendering field content, to stripping the html from a string. The library class was designed for use in Xslt where everything from c# wasn’t natively given to you, now with Razor views you have the entire world of c# at your fingertips. So you’ll notice things like the date formatting functions that were on ‘library’ are not on the UmbracoHelper, and that is because you can just use the regular c# way. Though, if you feel inclined that these methods should be on UmbracoHelper, another great thing is that this is not a static class so you can add as many extension methods as you like. I’d list all of the methods out here but I said I’d keep it short, your best bet currently is to just have a look at the class in the source code, or just see what great stuff shows up in intellisense in VS.
UmbracoContext
Though we did have another UmbracoContext class, this one is the new cooler one and the old one has been marked as obsolete. This new one’s full name is Umbraco.Web.UmbracoContext and it is a singleton so you can access it by UmbracoContext.Current but normally you shouldn’t have to access it by it’s singleton because it is available in all of your views and SurfaceControllers as a property. For example, to access the UmbracoContext in your view you simply use @UmbracoContext. This class exposes some handy properties like: UmbracoUser, PageId, IsDebug, etc…
Testing
If you are interested in MVC and Umbraco, it would be really really appreciated for you to take the time to download the beta, the latest nightlies or source code and give it a shot. Hopefully the docs are enough to get you up and running and if you run into any troubles please log your issues on the tracker. If you have any question, comments, etc… about the source code we’d love to hear from you on the mail list.
Pete will be putting up an MVC getting started post on the Umbraco blog real soon, so watch this space!
Adios!