In the next release of Glass.Mapper.Sc we will support mapping rendering parameters to object, in this post I will explain how we implemented this.

You can get a pre-release version of this from the Glass.Mapper builder server right now (see the download page to find out how).

I had recently been going through some of the Glass.Mapper.Sc unit tests and updating them to use a fake Item rather than an item pulled from the Sitecore database. To do this I created a method which I could pass a dictionary of Ids and values to the item which contained the field values:

        public static Item CreateFakeItem(Dictionary<Guid, string> fields, string name="itemName")
        {
            var id = new ID(Guid.NewGuid());
            var templateId = new ID(Guid.NewGuid());
            var language = Language.Current;
            var version = Sitecore.Data.Version.Latest;
            
            var itemDefinition = new ItemDefinition(id, name, id, ID.Null);
            var fieldList = new FieldList();

            foreach (var fieldId in fields.Keys)
            {
                fieldList.Add(new ID(fieldId), fields[fieldId]);
            }

            var itemData = new ItemData(itemDefinition, language, version, fieldList);
            var item = new Item(id, itemData, new Database("master"));
            return item;
        }

The problem with this method was that fields had to be reference by ID, they couldn't be referenced by the field name. This got me thinking about a possible solution and I wondered if the only requirement to get fields to work by name would be to specify a proper template ID. So I update the CreateFakeItem method to accept a template ID and a database:

        public static Item CreateFakeItem(Dictionary<Guid, string> fields, ID templateId, Database database, string name = "ItemName")
        {
            var id = new ID(Guid.NewGuid());
            var language = Language.Current;
            var version = Sitecore.Data.Version.Latest;

            var itemDefinition = new ItemDefinition(id, name, templateId, ID.Null);
            var fieldList = new FieldList();

            if (fields != null)
            {
                foreach (var fieldId in fields.Keys)
                {
                    fieldList.Add(new ID(fieldId), fields[fieldId]);
                }
            }

            var itemData = new ItemData(itemDefinition, language, version, fieldList);
            var item = new Item(id, itemData, database);
            return item;
        }

I then created a GetRenderingParameters method that would read the values in the rendering parameters string into the appropriate fields:

        public T GetRenderingParameters<T>(NameValueCollection parameters, ID renderParametersTemplateId) where T:class{

            var item = Utilities.CreateFakeItem(null, renderParametersTemplateId, SitecoreContext.Database, "renderingParameters");

            using (new SecurityDisabler() )
            {
                using (new VersionCountDisabler())
                {
                    item.Editing.BeginEdit();

                    foreach (var key in parameters.AllKeys)
                    {
                        item[key] = parameters[key];
                    }
                    T obj = item.GlassCast<T>();

                    item.Editing.CancelEdit();
                    return obj;
                }
            }

        }

Now that I had an item that contained my rendering parameters as field values I could send it through the normal Glass.Mapper mapping process using the GlassCast method. Finally I just needed to cancel the item editing to ensure no values are saved back to the database.

Using the method we now have a very quick way to make fake versions of items which are useful for unit testing, this is one of the tests for Glass.Mapper.Sc:

            //Assign
            string fieldValue = "3.141592";
            decimal expected = 3.141592M;
            var fieldId = Guid.NewGuid();

            var item = Helpers.CreateFakeItem(fieldId, fieldValue);
            var field = item.Fields[new ID(fieldId)];

            var mapper = new SitecoreFieldDecimalMapper();


            //Act
            var result = (decimal)mapper.GetField(field, null, null);

            //Assert
            Assert.AreEqual(expected, result);

If you look at the tutorial you will also see under "Other" that you can actually pass any query string formatted string to Glass.Mapper and have it mapped to a class as long as you have a matching template in Sitecore.

For more information on how to access rendering parameters using Glass.Mapper see

  • Tutorial 23 - Rendering Parameters
  • .
    comments powered by Disqus