Default values for variables in content parts

Topics: Writing modules
Feb 22, 2011 at 9:38 PM

I want to have a default value for my content part when someone creates one.

I've tried two things that haven't worked.

1. Setting a default value in the DataMigration like this:

.Column("Height", DbType.Int32, column => column.NotNull().WithDefault(400))

This did create the database tables as I expected, but creating a new content part didn't have the default in it.

2. Using the DefaultValue attribute in the content part like this:

[DefaultValue(400)]
public int Width
{
   get { return Record.Width; }
   set { Record.Width = value; }
}

Is either of these the right way to go, but I've done it wrong, or should I be doing something else?

Thanks,
Richard Garside.

Apr 4, 2011 at 1:34 PM
Edited Apr 4, 2011 at 1:49 PM

I tried exactly what you did, with the same result.

I only found one way to get it to work: using a handler. The handler allows you to provide code that will get visited when various events occur (i.e. handle part events).  In particular, you need to pass your default-value-setting code to the 'OnInitializing' method.

Here is an example part handler class that does what you're trying to do above:

using System;
using System.Collections.Generic;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Contrib.MyModule.Models;

namespace Contrib.MyModule.Handlers
{
    public class MyPartHandler : ContentHandler
    {
        public MyPartHandler(IRepository<MyPartRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
            OnInitializing<MyPart>((context, part) => {
                part.Width = 400;                            
              });
        }
    }
}

Coordinator
Apr 4, 2011 at 7:10 PM

Did you try setting them from the record constructor, which is what I see in about every place I looked for such things in the main project?

Apr 4, 2011 at 8:43 PM

Just recapping from our discussion over at http://excitabyte.wordpress.com/2011/04/04/262/ for viewers over here:

When a model derives from ContentPart instead of its generic counterpart ContentPart<TPartRecord>, then the record constructor isn't available (for all intents and purposes).  This happens to appertain to a few of the models in my project, so I tend to forget about TPartRecord, even when I shouldn't.   : )

As you kindly point out, for all but the rarest use cases, the TPartRecord constructor is the place to do it.  For the remainder cases, though, the above technique can be quite handy.

Coordinator
Apr 4, 2011 at 8:44 PM

Ah, I see, makes sense, yes.

Apr 5, 2011 at 9:40 AM

The record constructor works for me.

Seems obvious now.