Click here to Skip to main content
15,886,110 members
Articles / Web Development / ASP.NET

Update SharePoint UserInfo List with More Active Directory Info

Rate me:
Please Sign up or sign in to vote.
4.45/5 (5 votes)
19 Mar 2009CPOL2 min read 59.7K   371   16  
Shows how to write a job that updates the UserInfo list with more Active Directory information.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Reflection;
using System.Web.UI;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Globalization;

namespace Mullivan.SharePoint.WebControls
{
    public class SPFieldRenderer : Panel
    {
        private BaseFieldControl _bfc = null;
        private SPList _list = null;
        private SPField _spField;
        private TextBox _tbox = null;
        private string _value = null;
        private bool _isSearch = true;
        private Type _tList;
        private Type _tFieldMetaData = null;
        private Type _tSPField = null;
        private Type _tSPContext = null;
        private MethodInfo _miSetBoolValue = null;
        private MethodInfo _miSetFieldAttributeValue = null;
        private FieldInfo _fiSpField = null;
        private FieldInfo _fiContextItem;
        private FieldInfo _fiContextItemIdSet;
        private FieldInfo _fiListPermission;

        public SPFieldRenderer()
        {
            _tFieldMetaData = typeof(FieldMetadata);
            _fiSpField = _tFieldMetaData.GetField("m_fld", BindingFlags.Instance | BindingFlags.NonPublic);
            _tSPField = typeof(SPField);
            _tSPContext = typeof(SPContext);
            _miSetBoolValue = _tSPField.GetMethod("SetFieldBoolValue", BindingFlags.Instance | BindingFlags.NonPublic);
            _miSetFieldAttributeValue = _tSPField.GetMethod("SetFieldAttributeValue", BindingFlags.Instance | BindingFlags.NonPublic);
            _fiContextItem = _tSPContext.GetField("m_item", BindingFlags.Instance | BindingFlags.NonPublic);
            _fiContextItemIdSet = _tSPContext.GetField("m_isItemIdSet", BindingFlags.NonPublic | BindingFlags.Instance);
            _tList = typeof(SPList);
            _fiListPermission = _tList.GetField("m_EffectivePermMask", BindingFlags.Instance | BindingFlags.NonPublic);
        }

        public SPList List
        {
            get
            {
                return _list;
            }
            set
            {
                _list = value;
            }
        }

        public SPField Field
        {
            get
            {
                return _spField;
            }
            set
            {
                _spField = value;
            }
        }

        public string Value
        {
            get
            {
                if (_bfc != null)
                {
                    object value = _bfc.Value;
                    if (value != null)
                    {
                        return _spField.GetValidatedString(value);
                    }
                    else
                        return null;
                }
                else if (_tbox != null)
                    return _tbox.Text;
                else
                    return _value;
            }
            set
            {
                _value = value;
            }
        }

        public bool IsSearch
        {
            get
            {
                return _isSearch;
            }
            set
            {
                _isSearch = value;
            }
        }

        public bool IsValid
        {
            get
            {
                if (_bfc != null)
                    return _bfc.IsValid;
                else
                    return true;
            }
        }

        public void Validate()
        {
            if (_bfc != null)
                _bfc.Validate();
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnLoad(e);

            SPField spField = null;

            using (SPWeb web = _list.ParentWeb)
            {
                SPContext renderContext = SPContext.GetContext(this.Context, 0, _list.ID, web);

                //We need to reflect and impersonate an item so that the edit controls
                //will work properly. I hate how the engineers designed these edit controls
                //to be dependent on an actual item. 
                SPItem impersonateItem = _list.Items.Add();
                _fiContextItem.SetValue(renderContext, impersonateItem);
                _fiContextItemIdSet.SetValue(renderContext, true);


                SPList currList = renderContext.List;
                if (!currList.DoesUserHavePermissions(SPBasePermissions.AddListItems))
                {                
                    //We need to fake out the rendering control and make it think
                    //it has rights to the impersonating item
                    SPBasePermissions perms = (SPBasePermissions)_fiListPermission.GetValue(currList);
                    perms |= SPBasePermissions.AddListItems;
                    _fiListPermission.SetValue(currList, perms);
                }

                spField = GetField();

                //Changing the SPField is OK as long as we don't update it
                //SO NEVER ADD the line that updates this field!!!
                //Set our field properties so that they display properly
                _miSetBoolValue.Invoke(spField, new object[2] { "Sealed", false });
                _miSetBoolValue.Invoke(spField, new object[2] { "Hidden", false });
                _miSetBoolValue.Invoke(spField, new object[2] { "Required", false });
                _miSetBoolValue.Invoke(spField, new object[2] { "ReadOnly", false });
                spField.ShowInEditForm = true; 


                //No Editing control
                if (spField.Type != SPFieldType.Integer &&
                    //No Editing control
                    spField.Type != SPFieldType.File &&
                    //No Editing control
                    spField.Type != SPFieldType.Computed &&
                    //No Editing control
                    spField.Type != SPFieldType.Calculated &&
                    //No Editing control
                    spField.Type != SPFieldType.Attachments &&
                    //Can't find a work around for BuiltIn sealed feilds
                    !spField.Id.Equals(SPBuiltInFieldId._CopySource) &&
                    //This control has a bug that I can't figure out how to fix 
                    !spField.Id.Equals(SPBuiltInFieldId._ModerationStatus))
                {
                    _bfc = spField.FieldRenderingControl;
                }

                if (_bfc != null)
                {
                    _bfc.ID = this.ID + "spRenderControl";
                    _bfc.FieldName = spField.InternalName;
                    //Reflect and set our SPField specifically so that our changes above
                    //can be used.
                    _fiSpField.SetValue(_bfc, spField);
                    _bfc.ControlMode = SPControlMode.New;
                    _bfc.RenderContext = renderContext;
                    _bfc.ItemContext = renderContext;

                    this.Controls.Add(_bfc);

                    _bfc.Visible = true;

                    SetValue();
                }
                else
                {
                    _tbox = new TextBox();
                    _tbox.TextMode = TextBoxMode.MultiLine;
                    _tbox.ID = this.ID + "_tbox";
                    _tbox.Attributes["style"] = "height:50px;width:300px";
                    if (!Page.IsPostBack)
                    {
                        if (string.IsNullOrEmpty(_value))
                            _value = spField.DefaultValue;
                        if (string.IsNullOrEmpty(_value))
                            _value = string.Empty;
                        _tbox.Text = _value;
                    }
                    this.Controls.Add(_tbox);
                }
            }
        }

        private SPField GetField()
        {
            SPField spField = _spField;

            //If in search and the field is multichoice then we want to
            //convert the field to a choice field because searching a list
            //on multiple fields doesn't work
            if (_isSearch)
            {
                Type fieldType = spField.GetType();
                if (fieldType == typeof(SPFieldMultiChoice))
                {
                    SPFieldMultiChoice spMultiChoice = (SPFieldMultiChoice)spField;
                    SPFieldChoice newField = new SPFieldChoice(_list.Fields, spField.Title);
                    _miSetFieldAttributeValue.Invoke(newField, new object[2] { "ID", spField.Id.ToString() });
                    spField = newField;
                }
                else if (fieldType == typeof(SPFieldLookup))
                {
                    SPFieldLookup spLookup = (SPFieldLookup)spField;
                    spLookup.AllowMultipleValues = false;
                    spLookup.DefaultValue = string.Empty;
                }

                //Set the default value to empty string so that nothing can
                //be selected
                if (spField is SPFieldChoice)
                    spField.DefaultValue = string.Empty;
            }
            return spField;
        }

        private void SetValue()
        {
            if (_bfc == null || Page.IsPostBack)
                return;

            SPField spField = GetField();

            try
            {
                object obj = null;
                if (!string.IsNullOrEmpty(_value))
                {
                    if (spField is SPFieldDateTime)
                    {
                        //For some reason the GetFieldValue for the datetime control
                        //doesn't work properly so we need to generate the value ourselves
                        //if the value doesn't parse then we need to set it because if it's left
                        //null then the Value property will blow up.
                        DateTime dt = DateTime.MinValue;
                        if (DateTime.TryParse(_value, null, DateTimeStyles.RoundtripKind, out dt))
                            obj = dt;
                        else
                            obj = DateTime.Now;
                    }
                    else if (_isSearch && spField is SPFieldLookup)
                        obj = spField.GetFieldValue(_value.Replace(";#", ""));
                    else
                        obj = spField.GetFieldValue(_value);
                }
                else
                    obj = spField.DefaultValueTyped;

                if (obj != null)
                    _bfc.Value = obj;
            }
            catch { }
        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            //Try and set the value again in case the edit control doesn't support 
            //setting the value during on init
            SetValue();

            // Some of the controls get set to not be visible in the Onload, so we need 
            // to set them back to visible
            foreach (Control c in this.Controls)
                c.Visible = true;
            
            base.Render(writer);
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions