DCSIMG
December 2008 - Posts - David Birin's blog

December 2008 - Posts

SharePoint - Internal field names in Hebrew

A field (sometimes called a column) in SharePoint - represented in the object model by the SPField class, has two main properties which are used to identify it in code, the Title property and the InternalName property, the reason for the duplication is that the Title property can be changed from the GUI or translated into other languages, therefore if we want to write code which can be used without recompiling after every field name change in the GUI or recompiling for different languages we will use the InternalName .
For example:

  1. If you want to access the field which holds the last modification date of a list item you will use the InternalName property which has the value Modified and not on the Title which has the value Modified in English and השתנה in Hebrew.
  2. SPListItemCollection.GetDataTable() will return a DataTable with internal names as columns.

After understanding why it’s important to used internal names now let’s talk about the surprises, when you create a field in a list of a document library using the GUI, the name that was typed in the creation will be used as an internal name after some sort of encoding f.e. space character is encoded to _x0020_ Hebrew characters are also encoded if I create a field named שלום עולם the InternalName will be the following monster:
_x05e9__x05dc__x05d5__x05dd__x0020__x05e2__x05d5__x05dc__x05dd_

I wrote a function to do the transform between the encoded version and the decoded version.

The Encode function:

/// <summary>
/// This function converts strings in Hebrew (it can be used for other
/// languages too) to the hexadecimal presentation that is used by SharePoint
/// for internal field names
/// </summary>
/// <param name="inputString">The string to convert</param>
/// <returns>The converted string</returns>
public static string ConvertHebrewToUnicodeHex(string inputString)
{
    StringBuilder outputString = new StringBuilder();
    //convert the string to char array and manipulate the chars
    char[] charArray = inputString.ToCharArray();
    foreach (char c in charArray)
    {
        int charIntRepresentation = c;
        outputString.Append("_x" + String.Format("{0:x4}", (uint)System.Convert.ToUInt32(charIntRepresentation.ToString())) + "_");
 
    }
    return outputString.ToString();
}

The Decode function:

/// <summary>
///This function converts strings in the unicode hexadecimal presentation 
/// for Hebrew that is used by SharePoint to a string in Hebrew
/// </summary>
/// <param name="inputString">The string to convert</param>
/// <returns>The converted string</returns>
public static string ConvertUnicoeHexToString(string inputString)
{
    StringBuilder outputString = new StringBuilder();
    //Each char is represented in the following format
    // _x????_ (7 chars long) where ???? is number in hex 
    for (int i = 0; i < inputString.Length; i += 7)
    {
        string hexValue = inputString.Substring(i, 7).Substring(2, 4);
        char charCode = (char)UInt32.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
        outputString.Append(charCode);
 
    }
 
    return outputString.ToString();
}

Have fun…

David Birin

How to create an application in IIS6 using C#

Before the IIS7 era, we had no API for directly manipulating IIS, but we still needed to perform some actions like creating a virtual directory or an application (mostly used in installations).

Creating an application using the IIS GUI is done in the following way:

IIS-CreateApp

 

Creating it in code is a more complex task which is dived into 3 parts:

1. Finding the website in the IIS which we want to create the application underneath:

/// <summary>
/// This function looks for the path of a web site in IIS
/// </summary>
/// <param name="siteName">The name of the website we are looking for</param>
/// <returns>The requested path or String.Empty if not found</returns>
public string GetAdsiPathForSite(string siteName)
{
    try
    {
        DirectoryEntry entry = new DirectoryEntry("IIS://LocalHost/W3SVC");
        // Go over all the nodes in the iis
        foreach (DirectoryEntry site in entry.Children)
        {
            //Check if the node is a website (it can be ftp and more...)
            if (site.SchemaClassName == "IIsWebServer")
            {
                // site.Properties["ServerComment"].Value stores the website name
                object tempObj = site.Properties["ServerComment"].Value;
                string serverComments = "";
                if (tempObj != null)
                {
                    serverComments = tempObj.ToString();
                }
                //Compare the name of the website to the name we got as parameters
                if (serverComments == siteName)
                {
                  
                    return site.Path;
                }
 
            }
        }
    }
    catch (Exception ex)
    {
       //Do some exception handling
    }
 
    return string.Empty;
}

2. Creating a virtual directory (if not exists), you can’t create an application on a folder which is not virtual directory:

/// <summary>
/// This function creates an virtual directory on an IIS site
/// </summary>
/// <param name="parentPath">The path to the directory (without the directory name)</param>
/// <param name="name">The name of the directory</param>
public void CreateWebDirectory(string parentPath, string name)
{
    try
    {
        if (EntryExists(parentPath + "/" + name))
        {
            //Virtual dirctory already exists on IIS, there is no need to create one
            return;
        }
        using (DirectoryEntry entry = new DirectoryEntry(parentPath))
        {
            //Invoking the "Create" method which creates the virtual directory
            DirectoryEntry newEntry = (DirectoryEntry)entry.Invoke("Create", new
            object[2] { "IIsWebDirectory", name });
            newEntry.CommitChanges();
        }
      
    }
    catch (Exception ex)
    {
        //Do some exception handling
    }
}
 
/// <summary>
/// This fuction check if a virtual direcory exists in IIS
/// </summary>
/// <param name="path">The path to the virtual directory</param>
/// <returns>True if exists False otherwise</returns>
public bool EntryExists(string path)
{
    try
    {
        using (DirectoryEntry entry = new DirectoryEntry(path))
        {
            return entry.Guid != Guid.Empty;
        }
    }
    catch
    {
        return false;
    }
}

3. Create the application:

/// <summary>
/// This function creates an application from virtual directory
/// </summary>
/// <param name="path">The path to the virtual directory</param>
/// <param name="name">The name of the new application</param>
public void CreateApplication(string path, string name)
{
    try
    {
        using (DirectoryEntry entry = new DirectoryEntry(path))
        {
            //Invoking the "AppCreate2" method which creates the application
            entry.Invoke("AppCreate2", new object[1] { 3 });
            entry.Properties["AppFriendlyName"].Value = name;
            entry.CommitChanges();
        }   
    }
    catch (Exception ex)
    {
        //Do some exception handling;
    }
}

It took some time to resolve the above because it’s undocumented, I hope it will help you.

David Birin