Aidan Garnish

Collaboration Not Competition

Space in column names

When referencing columns programatically or in CAML that have a space in the name replace the spaces with _x0020_

For example "End Use" becomes "End_x0020_Use"

The format required to access non-alphanumeric column titles is this (IN LOWER CASE):

_x00[the hex code]_

Here are a few more examples:

Char         Code 

[space]      20      i.e. _x0020_
<            3C      i.e. _x003c_
>            3E
#            23
%            25
{            7B
}            7D
|            7C
\            5C
^            5E
~            7E
[            5B
]            5D
`            60
;            3B
/            2F
?            3F
:            3A
@            40
=            3D
&            26
$            24

To reference a column called “e-mail” you would need e_x002d_mail.

This page has a list of all the Hex Codes of some other symbols:http://www.asciitable.com/

Hit enter, fire a web part event the easy way

I have a custom web part search box that has a button next to it that directs the user to the search results page for the query that has been entered. What I also want to do is have that same code fire when the user presses enter. With the asp:textbox control this didn't look as if it was going to be very simple as the text changed event does not fire on every key press. Instead it fires when the control loses focus. 

Fortunately pressing enter causes the control to lose focus so it turns out that it is simple as calling the executequery method in the text changed event like this:

 void txtSearch_TextChanged(object sender, EventArgs e)
        {
              btnExecuteQuery_OnClick(this, e);
        }

Now, whenever a user hits enter the execute query event fires. Testing shows that clicking away from the textbox on a link or tabbing away from the textbox does not fire the event. Result!

Downloading and uploading documents to SharePoint with metadata

I need to copy some documents from a SharePoint 2003 server to a MOSS 2007 server to make them available on our Internet sites. This is quite easily achieved using the object model but what I also need is to move the metadata associated with the document so I can filter correctly on the Internet site.

To do this I have started by creating a couple of methods. One to download the document from SharePoint to a file system folder and create an xml document that contains the metadata in the same folder. The second method uploads the document with it the metadata to a destination SharePoint document library.

private void DownloadDocumentFromLibrary()
  {
   try
   {
    //get site
    SPSite oSite = new SPSite("http://Localhost");
    
    using(oSite)
    {
     //get the rootSite
     SPWeb oWeb = oSite.RootWeb;
    
     SPList oList = oWeb.Lists["Shared Documents"];

     foreach(SPListItem oItem in oList.Items)
     {
      //get meta-data for the item
      string strXML = oItem.Xml.ToString();
      TextWriter tw = new StreamWriter("c:\\MyDownloadFolder\\"+oItem["Name"]+".xml");
      //write xml to file
      tw.WriteLine(strXML);
      tw.Close();

      //get document
      byte[] binFile = oItem.File.OpenBinary();
      System.IO.FileStream fstream = System.IO.File.Create("c:\\MyDownloadFolder\\" + oItem["Name"]); 
      
      //write document to folder
      fstream.Write(binFile, 0, binFile.Length);
     } 
    }
   }
   catch(Exception err)
   {
    Console.WriteLine(err.Message);
   }
  }

The second method then takes the downloaded files and uploads them to the Internet server document library. You may need to find a way to physically move the files across the network using FTP or something similar depending on where your Internet server is and what security surrounds it.

private void UploadDocumentFromFileShare()
  {  
   try
   {
    //get site
    SPSite oSite = new SPSite("
http://Localhost");

    // Process the list of files found in the directory.
    string [] fileEntries = Directory.GetFiles(@"c:\mydownloadfolder");
    foreach(string fileName in fileEntries)
    {
     //check file type to see if it is an xml document
     int iFileNameLength = fileName.Length;
     string strFileExtension = fileName.Substring(iFileNameLength-4,4);
    
     if(strFileExtension != ".xml")
     {
      //Load the local file into a stream
      FileStream stream = File.OpenRead(fileName);
      byte[] content = new byte[stream.Length];
 
      //Read the file into a byte array
      stream.Read(content,0,(int)stream.Length);
      stream.Close();

      using(oSite)
      {
       //Get the rootSite
       SPWeb oWeb = oSite.RootWeb;
       //Get the folder that should store the document
       SPFolder folder = oWeb.Folders["upload"];

       string[] strSplitFileName = fileName.Split('\\');
       string strFileName = strSplitFileName[strSplitFileName.Length-1];
       //add document to library
       folder.Files.Add(folder.Url + "/" + strFileName, content,true);
 
       //get list
       SPList oList = oWeb.Lists["upload"];
       //create query to get added document item
       SPQuery oQuery = new SPQuery();
       oQuery.Query = "<Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='File'>"+strFileName+"</Value></Eq></Where>";
   
       SPListItemCollection oItems = oList.GetItems(oQuery);

       //get xml for document properties
       XmlTextReader reader = new XmlTextReader(fileName+".xml");
    
       XmlDocument doc = new XmlDocument();
       doc.Load(reader);
       XmlElement root = doc.DocumentElement;
       XmlNode node = root.Attributes.GetNamedItem("ows_Column1");
       string strColumn1= node.Value.ToString();

       foreach(SPListItem oItem in oItems)
       {
        string strTitle = "";
        strTitle = strFileName.Substring(0,strFileName.Length-4);
        oItem["Title"] = strTitle;
        oItem["Column1"] = strColumn1;

        oItem.Update();
       }
      }
     } 
    }
   }
   catch(Exception err)
   {
    Console.WriteLine(err.Message);
   }
  }

It is also possible to download attachments from an item using the following code:

 private void DownloadAttachmentFromItem()
  {
   //download attachment from a list to file system
   SPWeb web = new SPSite("
http://localhost").OpenWeb();
   
   //Open List
   SPList list = web.Lists["Doc List"];
      
   foreach(SPListItem oItem in list.Items)
   {
    //get meta-data for the item
    string strXML = oItem.Xml.ToString();
    TextWriter tw = new StreamWriter("c:\\MyDownloadFolder\\"+oItem["Title"]+".xml");
    tw.WriteLine(strXML);
    tw.Close();

    //Get the folder
    SPFolder folder = web.Folders["Lists"].SubFolders["Doc List"].SubFolders["Attachments"].SubFolders[oItem.ID.ToString()];
    //download attachment
    foreach(SPFile oFile in folder.Files)
    {
     byte[] binaryFile = oFile.OpenBinary();
     System.IO.FileStream fstream = System.IO.File.Create("c:\\MyDownloadFolder\\" + oItem["Title"]); 
     fstream.Write(binaryFile, 0, binaryFile.Length);
    }
   }
  }