T4MVC with Umbraco

Strongly-typed Umbraco

After the community moved on from code-first Umbraco, three options remain for developers keen to leverage strongly-typed models within their classes. I wrote about Umbraco Mapper on Medium last year, and Ditto has been getting a lot of mindshare recently. At Epiphany we are big fans of Zbu.ModelsBuilder, which my colleague Tom Pipe blogged about last year.

They are all approaches a developer can use to get strongly-typed models for use in their controllers and views without resorting to literal strings with @Model.Content.GetPropertyValue<string>("propertyName") calls littered throughout your templates.

The one place that I still use literal strings in my projects is with my liberal use of partial views.

@Html . Partial ( "Partials/Navigation" ) @foreach ( var profile in profiles ) { Html . RenderPartial ( "Partials/Profile" , profile ); }

These strings cause all sorts of headaches when you make typos or start renaming partials. You won’t find out about these errors until runtime. In some complex scenarios, you might not catch all these issues through testing. This isn’t a problem that is unique to Umbraco - ASP.NET MVC suffers from these same issues.

T4MVC

I’ll just shamelessly borrow the description from the GitHub page.

T4MVC is a T4 template for ASP.NET MVC apps that creates strongly typed helpers that eliminate the use of literal strings in many places.

I won’t cover everything that T4MVC does here, you should check out the GitHub page for that. After installing in your project (and the companion VS extension), you can solve the problem above with an automatically generated strongly-typed helper.

@Html . Partial ( MVC . Views . Partials . Navigation ) @foreach ( var profile in profiles ) { Html . RenderPartial ( Mvc . Views . Partials . Profile , profile ); }

Now the original problems disappear. If you mistype the partial name or rename a partial, your controllers won’t compile. You can enjoy IntelliSense while writing your templates.

BeginUmbracoForm

You will still end up using literal strings if you are using SurfaceControllers and Html.BeginUmbracoForm for your form submissions. T4MVC gets around the problem with the standard Html.BeginForm helper by providing extension methods in the T4MVCExtensions assembly (see here).

The following snippet can be used to leverage the generated T4MVC code and avoid literal strings.

public static class UmbracoExtensions { public static MvcForm BeginUmbracoForm ( this HtmlHelper htmlHelper , ActionResult result , FormMethod formMethod ) { var callInfo = result . GetT4MVCResult (); return htmlHelper . BeginUmbracoForm ( callInfo . Action , callInfo . Controller , formMethod ); } }

This will allow you to use the BeginUmbracoForm method like below (assuming you have a SurfaceController called ContactFormController with an action called Submit )

@using ( Html . BeginUmbracoForm ( MVC . ContactForm . Submit (), FormMethod . Post )) { @Html . TextBoxFor ( m => m . Name ) }

There are some gotchas with forms and T4MVC, so make sure you read the documentation.

You will have to create an override for each BeginUmbracoForm method you wish to use however.