With WSS 3.0 / MOSS 2007 it is now possible to create custom field types and field control. These constructs are exciting in that they can be used to expose complex data types in SharePoint site columns. For example, if you'd like to capture and store structured data such as an address, a social security number or a phone number that is now possible with a few custom code pieces. In fact the default SharePoint fields such as text, lookup and choice all use this same infrastructure to exposes data to SharePoint lists and page layouts.

The field type class is the native field type implementation that is used to create new site columns and list fields.

Read more here:
Custom Field Type Definition
How to: Create a Custom Field Type and Field Control


Here's how I create a custom field type and field control:

  • Create the Field Control class
    This class is a server control that is used by the edit form or placed on a page layout to exposes data in your custom field type. It includes any formatting necessary for "view" mode and any input controls necessary for "edit" mode.

    In this example I am creating a simple field control that exposes a text field type with minimal formatting and a text input box for editing. Note the "Value" property override, this property is used by the SharePoint framework to get the value of the field when editing in a page layout or item edit form.

    Server Control Class:
    public class MyCustomFieldControl : BaseFieldControl {
    
        private DropDownList _editor;
        private Literal _litvalue;
    
        public override object Value {
            get {
                return (ControlMode == SPControlMode.New 
                            || ControlMode == SPControlMode.Edit)
                        ? _editor.Text : ListItemFieldValue;
            }
            set {
                base.ItemFieldValue = value;
            }
        }
    
        protected override void OnInit(EventArgs e) {
            base.OnInit(e);
            EnsureChildControls();
        }
    
        protected override void CreateChildControls() {
            Controls.Clear();
            base.CreateChildControls();
    
            if (ControlMode == SPControlMode.New 
                    || ControlMode == SPControlMode.Edit) {
                _editor = new DropDownList();
                Controls.Add(_editor);
            } else {
                _litvalue = new Literal();
                _litvalue.Text = Convert.ToString(ListItemFieldValue);
                Controls.Add(_litvalue);
            }
        }
    }
  • Page Layout Declaration:
    <controls:MyCustomFieldControl 
        id="MyCustomFieldControl1" 
        Runat="server" 
        FieldName="Field1" />
    
    • Create the field type class
      The field type class in the native implementation of the field behavior including the base type and the field rendering control. Here's an example:
      public class MyCustomField : SPFieldText {
          
          public MyCustomField(SPFieldCollection fields, string fieldName) 
              : base(fields, fieldName) {
          }
      
          public MyCustomField(SPFieldCollection fields, string fieldName, string displayName) 
              : base(fields, fieldName, displayName) {
          }
      
          public override BaseFieldControl FieldRenderingControl {
              get {
                  BaseFieldControl fldControl = new MyCustomFieldControl();
                  fldControl.FieldName = InternalName;
                  return fldControl;
              }
          }
      }


    • Register the field type class
      Once the field type class is implemented and the assembly is deployed to your web frontend, you will need to register this new field type with the SharePoint runtime. To do this you need to add an xml configuration file to the 12/Template/XML directory named fldtypes_<custom name>.xml where <custom name> is a unique name associated with your customization. You can also view the default SharePoint field types registration XML configuration files in this directory.
      <FieldType>
          <Field Name="TypeName">My Custom Field</Field>
          <Field Name="ParentType">Text</Field>
          <Field Name="TypeDisplayName">My Custom Field</Field>
          <Field Name="TypeShortDescription">My Custom Field</Field>
          <Field Name="FieldTypeClass">MyCustomField, MyCustomFieldAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1df43608d339111</Field>
          <Field Name="UserCreatable">TRUE</Field>
      </FieldType>
      


    Now that the field type is registered with SharePoint, you should now be able to create a new site column or list field based on this new custom field type.

It is possible to manipulate the web.config file globally by using a little known feature in SharePoint that allows developers to describe a set of changes by using an XML customization file. In fact, both SharePoint and MOSS use this mechanism to publish web.config changes when a web application is created.

  • Create the customization file
    The customization file is used by SharePoint to apply changes to the web.config file when a web application is created. Any changes that are inside the customization file will be applied to all web applications globally. This method of customization does not work for cases where you would like to apply web.config changes to only a specific web application.

    In this case I am adding a custom HttpModule to the web.config file. The web.config node will be appended as a child to the configuration/system.web/httpModules node. The id attribute needs to be unique. Everything inside the add node will be appened as a child to the node specified in the path attribute.
    <?xml version="1.0" encoding="utf-8" ?>
    <actions>
    
        <add 
            path="configuration/system.web/httpModules" 
            id="{8DD2A7B1-0223-4be8-B1B5-339B642EFB21}">
            <add name="MyHttpModule" 
                type="MyHttpModule, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1df43608d33992f" />
        </add>
    
    </actions>
    


  • Copy the customization file to the web front-end
    The xml customization file needs to be placed the <sharepoint install root>\12\Config directory and it needs to be named webconfig.<custom name>.xml where <custom name> is a name specified to your customization.

    You can take a look at the 12\Config directory to see examples of web.config customizations that are applied by SharePoint and MOSS. You will see that you can not only add nodes to the web.config but also remove or update nodes that exist in the web.config file.

As SharePoint becomes more prevalent in the custom application development realm, there has been some friction and malcontent expressed in relation to deployment processes, team development methods and application upgrade paths. I believe that Microsoft has fallen short on providing the tools necessary to promote and support custom application development on the SharePoint platform.

In my opinion, the SharePoint platform should not limit nor impede my ability as a custom application developer to deliver solutions that follow the same deployment principals as any other custom asp.net application. As some readers may be aware, at present the standard Microsoft guidance is flawed because it does not fully support repeatable build processes. This is a huge barrier for custom application developers who are accustom to building applications using source control for all assets, build automation and continuous integration. SharePoint as a lot to offer but taking advantage of the platform as a vehicle for custom applications should be more congruent with standard software development practices.


The Microsoft approach

The Microsoft approach dictates that for team development environments, artifacts such as aspx, html, css files or any other file that lives in the content database should be created, stored and version controlled in a SharePoint authoring environment. These artifacts are created and maintained by "content developers". These content developers use SharePoint designer to create and propagate changes to production.

In parallel, custom application developers are to use standard team development principals (source control, etc) to create assemblies that are then promoted to the authoring environment where they are tested and eventually deployed to the production environment.

Read more:
http://msdn2.microsoft.com/en-us/library/bb428899.aspx


Where the Microsoft approach falters

The primary problem with the Microsoft approach is that in many cases there is a hard dependency between artifacts and assemblies. You need to have the same version of artifacts and assemblies to be able to test in any environment and it is not possible get a synchronized version of both sets of assets from a single source. This relegates developers to constantly migrating and updating both content and assemblies to get a consistent version to test. The problem is only compounded because content authors may not be technically able to update assemblies in the authoring environment.

For a custom application of any complexity you need to be able to build and deploy a set of files that work as a unit. For a standard data-driven (SQL Server) asp.net application that means you would have your database creation scripts in source control and when deploying to a new environment (or upgrading an environment), you would run your scripts to create a new copy of the database for that environment. This way, deploying to a test environment becomes easy because you have a repeatable process. Why treat a SharePoint site any differently? You will of course need to use the SharePoint API instead of a SQL database creation script, but the basic function is the same.


A Solution

After working with SharePoint for 6+ years I have found that it is possible to treat a SharePoint custom application as you would any other asp.net custom application. The Microsoft tools (and therefore the approach) fall short on these topics but with some motivation and know-how you can achieve substantial benefits by following these steps: 

  • Use SPDeploy
    Ok, this is shamefully self promotional. What I really mean is that you should be using a deployment tool that can support creating customizations inside Visual Studio and deploying those customization via a SharePoint Solution Package (.wsp) to a remote server. There are a few tools that compile a wsp from Visual Studio such as WSPBuilder or Andrew Connell's custom approach. In my opinion SPDeploy is the most complete and easily repeatable solution to solve this problem, but I am biased :)

  • Create all your SharePoint customizations inside Visual Studio
    We are custom application developers and we use Visual Studio solutions. This should not change when you are working on a SharePoint project.

  • Use source control
    Because we now have all of our SharePoint customizations inside Visual Studio, the next logical step is to commit that solution to source control. Read more about the benefits of source control:
    http://msdn2.microsoft.com/en-us/library/ms173539.aspx

  • Design your solution to provision all site collection assets from source control
    Provisioning all site collection assets enables you to create your projects site collection from source control at will. This means that when a new developer steps onto your project, he or she can pull a copy of the files from source control and create a site collection that is identical to your site collection. Furthermore because you now have a repeatable site collection provisioning process, when deploying to test you can hand-off your wsp and have a tester create a site instance in no time at all.

    Implementing this can be a bit tricky. For a brute force approach you can create a feature that lives at the site level that will provision all sub sites, files, etc. Or if you are adventurous you can create an XML configurable feature that will provision all assets according to a configurable XML file.

  • Use developer isolated environments
    Because we have the infrastructure in place to provision all site collection assets, it is possible to create isolated developer environments. This is the standard development method for any asp.net application and it should not change when developing a custom application on top of SharePoint.

  • Use continuous integration
    This one is somewhat optional but I would strongly recommend using continuous integration on any project. Because of the previous points, continuous integration for a SharePoint project becomes possible. Read more about continuous integration:
    http://en.wikipedia.org/wiki/Continuous_integration

  • Use SharePoint Designer only as a "Immediate Feedback" tool
    SharePoint designer should not be used as a primary development tool (as MS suggests) but rather as a tool to quickly and conveniently see changes inside your site instance. Once you are happy with a change, then it should be placed in your Visual Studio solution so that it can participate in source control.

    This is usually helpful with rendering assets such as page layouts, XML files, XSLT transforms and stylesheets. It sure is nice to be able to see changes immediately, but be sure to commit your changes to your Visual Studio project (and hence source control) so that they are visible to other developers on the project.
top