Inconvenient GetCustomProperty and SetCustomProperty

So, I’m working on a custom field definition for SharePoint. My field has a few custom properties that you need to fill in when you create it. However, after creation, those fields were empty – they were simply never set. You could then update them, and that worked fine, but creation was broken.

The code I’d inherited was trying to solve this problem (it’s a known issue) this way – which is a bit ugly. It also holds memory for the Dictionary of values that, as far as I could see, was only being freed on IISReset. Yuck. And it didn’t work in our code, despite matching the example in that thread quite closely.

Fortunately, I came across a neat post on Gunnar Peipman’s blog – Temporary Solution for GetCustomProperty an SetCustomProperty Errors. I don’t like using reflection to invoke the methods I need to use, but at least it’s a solution, even if not ideal. And it works!

Please go to Gunnar’s post – but just in case his blog goes down, I’m going to shamelessly plagiarise his code below…

Thanks Gunnar!

Uses the System.Reflection API.

        private void SetFieldAttribute(string attribute, string value)
        {
            Type baseType;
            BindingFlags flags;
            MethodInfo mi;

            baseType = typeof(SemaphoreField);
            flags = BindingFlags.Instance | BindingFlags.NonPublic;
            mi = baseType.GetMethod("SetFieldAttributeValue", flags);
            mi.Invoke(this, new object[] { attribute, value });
        }

        private string GetFieldAttribute(string attribute)
        {
            Type baseType;
            BindingFlags flags;
            MethodInfo mi;

            baseType = typeof(SemaphoreField);
            flags = BindingFlags.Instance | BindingFlags.NonPublic;
            mi = baseType.GetMethod("GetFieldAttributeValue",
                                        flags,
                                        null,
                                        new Type[] { typeof(String) },
                                        null);

            object obj = mi.Invoke(this, new object[] { attribute });

            if (obj == null)
                return "";
            else
                return obj.ToString();
        }
Advertisements
Inconvenient GetCustomProperty and SetCustomProperty

5 thoughts on “Inconvenient GetCustomProperty and SetCustomProperty

  1. Steve Dawkins says:

    I too have used this approach in WSS 3.0 / MOSS. There is a problem with the use of Field Attributes as they are persisted to the element as attributes which are unknown to SharePoint’s schema for Field.

    This is a big problem is SharePoint Foundation and 2010 when saving site templates as these are now wsp solutions and that fail to activate id any unknown attributes are present on Field elements.

    I’ve just re-tested SetCustomProperty under 2010 and it still does not persist any value?

  2. Steve Dawkins says:

    Back on this again and determined to understand the issues:

    1. Get and SetCustomProperty do work but you have to declare the properties in your _fldtypes… xml using .

    2. The persistence issue fully explained in the Storing Field Settings section of this article:

    http://msdn.microsoft.com/en-us/library/cc889345(v=office.12).aspx#CreatingWSS3CustomFields_StoringFieldSetting

    The article clearly explains how and where any metadata should be stored and more importantly gives a SharePoint farm safe method of working; enjoy otherwise it will drive you nuts.

  3. Alex says:

    I think the problem is two-fold
    1) SetCustomProperty requires the field definition (in the fldtypes_XXX.xml) to have the properties defined, like this:

    If this is missing, SetCustomProperty() does nothing.

    2) the New and Edit page overwrite (?) the values you just saved in your custom field editor. (not sure what happens exactly)
    A simple solution: read all the custom properties in both field constructors (using GetCustomProperty() ), and override the field’s Update() to use SetCustomProperty() to write your custom property values:

    public CustomField(SPFieldCollection fields, string fieldName)
    : base(fields, fieldName)
    {
    ReadCustomProperties();
    }

    public CustomField(SPFieldCollection fields, string typeName, string displayName)
    : base(fields, typeName, displayName)
    {
    ReadCustomProperties();
    }

    public override void Update()
    {
    WriteCustomProperties();
    base.Update();
    }

    Hope to help.
    Alex

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.