Microsoft’s Content Management Server 2002 (hereafter MCMS) contains many types of assets such as Channels, Postings, Templates, & Resources that are used to store data for a CMS site. One feature Microsoft provided is the ability to wrap these objects with some metadata… otherwise known as custom properties. These custom properties can be managed through the included MCMS Site Manager utility. Developers can also interact with these properties via the publishing API (PAPI).
However, with all that Microsoft as provided with custom properties, there are some very notable issues when working with custom properties. Recently I embarked on a project where these limitations were just too glaring, so I decided to create an alternative solution: CustomPropertyDbEx.
At first my goal was to address issues with my current project, but I quickly realized how much other developers could benefit from it. So this effort quickly changed into making this library a replacement for the MCMS custom properties, giving developers every reason to use CustomPropertyDbEx instead of using the MCMS custom properties. While not for everyone or every MCMS project, I’m sure this will help quite a few people out based on my experience, discussions with some MCMS MVP’s, and from the microsoft.public.cmserver newsgroup. I welcome any feedback you may have.
Limitations of MCMS Custom Properties
First, I want to be very clear: the custom property mechanism and management options Microsoft provided out-of-the-box with MCMS (and SP1/SP1a) is a great solution… it’s something I’ve used in my MCMS projects. However there are some limitations to what’s provided out of the box… the most important in my mind are:
- Management: you manage most of the custom properties with Site Manager. Authors also have the ability to manage custom properties on postings they create or have rights to. But there are things you can’t do:
- Create/delete custom properties for channels via PAPI… you can access and edit their values, but you must create all properties in Site Manager first
- Copy custom properties between CMS assets… you can’t just say “copy all these properties from one channel to another”
- Exporting properties from one environment to another - Stefan recently released a server control to add to the author console to allow users to edit custom properties while in authoring mode, making it a little easier to manage the properties.
- Searching: you don’t want to search custom properties using the provided methods in the PAPI because it’s a big performance hit
While they may not seem like big deals, the two things above created a process and management challenge, as well as adversely affected the application’s performance when I had to find a specific custom property.
Overview
Basically I created a small database schema (1 table and 9 stored procedures) to store the properties, an assembly to manage the properties in the database and provide functionality to a calling application, and a web-based management application. I took great care to mimic Microsoft’s naming conventions for all objects and methods so there wouldn’t be much work required in modifying existing MCMS solutions to use the CustomPropertyDbEx.
I have extended the MCMS model that allows Channels, Postings, Templates, and Resources to have custom properties to the following types of CMS assets (see the CustomPropertyDbExAssetType enumeration for all available custom property types):
- Site: assign site-wide custom properties (like global variables)
- Other: for use when one of my MCMS asset types doesn’t suit your needs
Each custom property has the following attributes (see the CHM documentation for details on each of these):
- Guid: unique identifier
- AssetType: type of the MCMS asset this property belongs to
- AssetGuid: unique identifier MCMS assigns to it’s assets; you can assign your own GUID or other unique identifier for the
CustomPropertyDbExAssetType.Site
andCustomPropertyDbExAssetType.Other
properties you create - Key: the property key value; this is not unique to each MCMS object… you can add multiple properties with the same key to implement a collection
- Value: the actual custom property value
Three objects makeup the bulk of CustomPropertyDbEx:
- CustomPropertyDbEx: custom property object with information linking it back to a CMS asset (channel, template, posting, resource, site, or other).
- CustomPropertyDbExCollection: a collection of CustomPropertyDbEx objects.
- CustomPropertyDbExGlobal: static management-like class that contains a .Searches static class, similar to CMS’ CmsContext.Searches static class.
Requirements
CustomPropertyDbEx has four dependencies:
- It must run on a server with MCMS SP1 installed (contains references to the Microsoft.ContentManagement.Publishing.dll assembly)
- Database populated with CustomPropertyDbEx schema must exist (this should be separate from your MCMS database)
- Your application (web/windows) *.config file must include a connection string pointing to the above database
- Microsoft’s Data Application Block: used by the CustomPropertyDbEx.dll to work with the database (included in the project)
Implementation
Follow these three quick steps to allow your project to use the CustomPropertyDbEx:
- As the requirements above indicate, you need to create a new database & populate it with the database schema
- Add a reference to the CustomPropertyDbEx & MSDAB in your project:
- ContentManagement.Extensions.CustomPropertyDbEx.dll
- Microsoft.ApplicationBlocks.Data.dll
- Add a connection string application variable to your project’s *.config file with the following format:
Now your project is ready… just add the code!
Using CustomPropertyDbEx in your projects
I’ve already gone over implementation above so you know how to get it into your project. Keep in mind that the CustomPropertyDbEx assembly uses a transaction-like commit to save the changes to the database. Whenever you do anything to a property from creating a new property, deleting one, or updating one’s values, you’ll need to call Commit()
on the property. I’ve added a Commit()
method to the collection to run commit on all items in the collection to make it a little easier to implement.
Code Samples
Here’s how you’d create two properties for a MCMS channel:
Once you’ve created a few properties, you need to be able to get them back; this is accomplished with one line of code. There are two methods in this code sample; the first one returns all custom properties for the provided channel; the second one gets all properties for the provided channel with a specific key supplied:
Once you have a property you’ll want to do something with it. The following example shows how you’d write it in a console app.
Methods Worth Mentioning
I’m one of those people who add more methods and ways to access data than probably necessary. You get to benefit from that. For example, I created 10 different constructor overloads to create new properties, and that’s only the public constructors. There are also quite a few “searching” type methods in the CustomPropertyDbExGlobal.Searches
static class such as:
- GetByAssetType: finds the custom property(s) matching a specific asset type
- GetByGuid: finds the custom property matching a specific guid
- GetByKey: finds the custom property(s) matching the specific property key
- GetByValue: finds the custom property(s) matching the specific property value
- GetByProperties (8 overloads): Retrieves all custom properties for the specified MCMS object
Where to get more documentation
The code is heavily documented, both inline and with XML comments. I’ve also created two CHM help files. One contains all methods and properties; the other contains only public and exposed classes, properties, and methods.
Managing CustomPropertyDbEx properties with the CustomPropertyDbEx Manager
While an assembly is provided to interact with the custom properties in your application, I found it’s sometimes easier to interact with them via management application similar to MCMS’s Site Manager. Included in the downloads of this article is an ASP.NET application you can use to manage your CustomPropertyDbEx store.
Some features of the CustomPropertyDbEx Manager:
- Browse any channel, posting, template, or resource and instantly view their properties
- Add, edit, and delete any property for any MCMS asset
- Save all custom properties for a MCMS asset as a template (with/without their data)
- Apply custom property templates to other MCMS assets (this makes it very easy to duplicate properties across channels or other items)
- Create and manage MCMS custom property templates
- Remove all values for all custom properties for a specified MCMS asset
- Remove all custom properties for a specified MCMS asset
Installation
Installation is fairly easy… put the ASP.NET application anywhere you like, then create a virtual directory pointing to it. You’ll also need to update the web.config to point to the correct database where the CustomPropertyDbEx properties are stored. What I did was create a “CustomPropertyDbExManager” web application under the MCMS web application created by the MCMS installation.
There are a few limitations to the manager that I plan to address in future versions. Refer to the roadmap for more information on this.
Converting MCMS custom properties to CustomPropertyDbEx with MigrateMcms2CpDbEx
Using the CustomPropertyDbEx in new MCMS application is simple, but what about retrofitting existing applications? I’ve added a console app that will walk through all channels and templates in the current hierarchy and create copies of their properties in a CustomPropertyDbex format. Check out the MigrateMcms2CpDbEx console utility for more information in the downloads associated with this article (linked at the end).
- CustomPropertyDbEx v0.2.0.0.zip: main assemblies required for implementation (dependent object as well)
- DatabaseSchema v0.2.0.0.zip: DDL files to create database objects
- IIS_CmsExtensionAdmin v0.2.0.0.zip: web app for GUI custom property management
- CHM All - CustomPropertyDbEx v0.2.0.0.zip: CHM help file documentation for ALL objects, methods, & properties (including private, internal, and protected members)
- CHM Public - CustomPropertyDbEx v0.2.0.0.zip: CHM help file documentation for exposed public objects, methods, & properties
- MigrateMcms2CpDbEx v0.2.0.0.zip: console app used to copy MCMS2002 custom properties to CustomPropertyDbEx database
Roadmap
What’s the first thing you hear from people after you publish something new after the “this is great, thanks!” or “interesting, but I have no use for it”? That’s an easy question: “What next” or “You know what you should add…”
I shared v0.1 with Stefan and Angus who had some great feedback. Some of which was incorporated into the current version. Many of the future features were added based on feedback from them. If you have ideas for additional features, please feel free to pass them along!
v 0.2
BUG FIXES
- Make sure can retrieve a collection of properties using the same key
ENHANCEMENTS
- Add methods to get all CMS objects that have a specific key, key-value, or key-value-assettype (with one of them being null)
- Possible to rename PropertyValue & PropertyKey -» Value & Key?
- Add additional comments, including code samples, to the XML comments
- Console app to copy properties from CMS object to database
- WebForm application to add & manage custom properties
- export/import properties (delayed to v.3)
- copy properties from one object to another
- add/edit/remove properties
v 0.3
BUG FIXES
- TBD
ENHANCEMENTS
- Create installer
- CustomPropertyDbEx Manager
- export/import properties
- ability to manage non channel/posting/template/resource assets
- Server control to add to authoring console to manage a channel/posting/site custom properties
- Include some sort of test “CanBrowseTo” when channels/postings/etc are returned from search to filter out the current user’s context
- Ability to set a flag saying “show all | show what I can see”… then let search filter out what the current logged in user can/can’t see
- Maybe if they provide a CmsContext can use that?
- For collection delete/commit… implement transaction to roll back all
- Create custom exceptions for things like “propertydoesn’texist”, etc
- Add SQL FullText searching for property keys & values