How to create your own ViewModels in DD4T 2.0

This post is part of a series. In the previous article I explained what ViewModels are and why they are useful. I imagine you are all excited about this, so let’s see how you can create your own ViewModels in a few minutes!

First of all, you need to have the following before we can get started:

Since a ViewModel is basically a .NET representation of a schema, we will start by creating a simple practice schema with the following properties:

General schema properties
Title Press release
Root element name pressrelease
Fields
headline Text, single value
body Rich text, single value

Next, open your ASP.NET MVC site in Visual Studio. Create a new class named PressRelease in a logical location (like the Models folder in your web application, or something). The namespace can be anything you like. Make the class extend the abstract class DD4T.ViewModels.ViewModelBase:

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  public class PressRelease : ViewModelBase
  {
  }
}

Next, we need to add an attribute to mark the class as a ViewModel. To do that, add the following code to your class:

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  [ContentModel("pressrelease", true)]
  public class PressRelease : ViewModelBase
  {
  }
}

Notice that we added two parameters to the ‘ContentModel’ attribute:

  • The first is the root element name of a schema. The system is now able to bind component presentations to your ViewModel automatically, by matching this value against the root element name of the schema.
  • The second is a boolean, telling the system whether or not it should include this model when it is scanning for ViewModels to bind to. If that sounds cryptic, just set it to true and you’re good.

Now that we have a class to represent a schema in Tridion, let’s turn our attention to the schema fields. As the overview above shows, our schema has a property called ‘headline’. That is to say: the property has an xml name with the value headline.

To use this field in our model, we need to create a property for it. Since it is a single-value text field, the most obvious choice would be to create a property of the type string, like this:

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  [ContentModel("pressrelease", true)]
  public class PressRelease : ViewModelBase
  {
    public string Headline { get; set; }
  }
}

And of course we need to somehow tell the system that this property is related to a particular field in the schema. We use another attribute for this purpose: TextField.

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  [ContentModel("pressrelease", true)]
  public class PressRelease : ViewModelBase
  {
    [TextField(FieldName="headline")]
    public string Headline { get; set; }
  }
}

As you can see, the attribute has a named parameter ‘FieldName’. This should contain the XML name of the field in the corresponding Tridion schema.

You might wonder why you need to specify a field name at all. Isn’t it enough to define a property with the same name? The answer is: yes! The FieldName parameter is optional, and is only required if the field name is different from the property name. Note that the casing is allowed to be different: by convention, XML field names in Tridion are usually all lower case, while .NET properties are camel-cased (with an upper case first letter).

Now that we know all that, we can simplify our code a bit:

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  [ContentModel("pressrelease", true)]
  public class PressRelease : ViewModelBase
  {
    [TextField]
    public string Headline { get; set; }
  }
}

Finally, let’s add the field ‘body’ to our ViewModel as well. This is a rich text field, and we can model it like this:

    [RichTextField]
    public MvcHtmlString Body { get; set; }

The final class now looks like this:

using DD4T.ViewModels.ViewModelBase;
namespace My.Namespace
{
  [ContentModel("pressrelease", true)]
  public class PressRelease : ViewModelBase
  {
    [TextField]
    public string Headline { get; set; }
    [RichTextField]
    public MvcHtmlString Body { get; set; }
  } 
}

In the next article, we will look at some other field types, like numbers and dates. Plus we’ll see how to model multiple value and metadata fields.