Basic operations with Domino .NET API for export purposes

This post is a very short guide on how to access a Notes database and read the data with a .NET application using Lotus Notes Interop. The code snippets are not optimized for use in a .NET application for continues access to Notes database. Its more meant for one time execution for export purposes. I’ve used the code presented here in a migration process from Lotus Notes document management solution to a custom SharePoint document management solution. Of course in that process I’ve developed other tools as needed to manipulate the data and documents before uploading to SharePoint as well as tools to upload and for post-upload data manipulation. As the title states this post is only for the first part, getting information out of Lotus Notes.

The code samples are tested and used on a PC with Windows 7 and Notes 7 client installed.
There is some Lotus Script presented too. For that part Domino Designer 7 is used.

Short Introduction to Notes databases

It’s important to know that Notes database is not a relational database but a document-centric database.
For people with SQL Server background it may be helpful to make a loose parallel between Notes database and a SQL database table.
A Notes database contains views.
Think of a view in Notes database as a SQL database table.
A document in a Lotus Notes database is similar to a row in a SQL table.
Documents in Notes database contain items which are similar to fields in a table in SQL with one big difference being that an item in Notes DB can have one or more objects (array of objects).
As mentioned before this is a very rough comparison between Notes database and SQL database and its meant just for getting an idea what is what in Notes DB in case you have never worked with Lotus Notes before.

Initialize Lotus Notes session

Reference to Interop.Domino.dll is required to be added in the project.

using Domino;

NotesSession lotusNotesSession = new NotesSession();
lotusNotesSession.Initialize("yourPassword");

Get and Open a Notes database

NotesDatabase localDatabase = lotusNotesSession.GetDatabase("ServerName", "DatabaseName.nsf", false);
localDatabase.Open();

In some cases this didn’t work for me and I had to loop through all the databases to get the DB I needed

NotesDbDirectory dbDict = lotusNotesSession.GetDbDirectory("ServerName");
NotesDatabase localDatabase = dbDict.GetFirstDatabase(DB_TYPES.NOTES_DATABASE);
while (localDatabase != null)
{
	if (localDatabase.Title == "DatabaseName")
		break;
	else
		localDatabase = dbDict.GetNextDatabase();
}

localDatabase.Open();

Get all the views of a database

public List<NotesView> GetAllViews(NotesDatabase localDatabase)
{
   object[] viewsArray = localDatabase.Views;
   List<NotesView> views = new List<NotesView>();

   foreach (object viewObject in viewsArray)
   {
      NotesView oneView = oneObject as NotesView;
      views.Add(oneView);
   }
   return views;
}

Get a view with a given name

NotesView view = localDatabase.GetView("ViewName");

Get the items names for a document

		
public List<string>	GetItemNames(int id)
{
	NotesDocument document = view.GetNthDocument(id);
	object items = document.Items;
	Array itemArray = (System.Array)items;
	List<string> itemNames = new List<string>();

	for (int icount = 0; icount < itemArray.Length; icount++)
	{
		NotesItem item = (Domino.NotesItem)itemArray.GetValue(icount);
		itemNames.Add(item.Name);
	}
	return itemNames;
}

Get items value for all documents in a view

For simplicity this method returns list of strings, every string containing metadata for a document. Values of the items are separated with the characters combination “;;;###”. If an item has more than one object in the object array then they are all added by separating them with the characters combination “;###”.
Also for simplicity this method takes all the items values as string. It can be modified as needed to deal with other types.

public List<string> GetDocumentsMetadata(NotesView view, List<string> itemNames)
{
	List<string> metadata = new List<String>();
	
	NotesDocument document = view.GetFirstDocument();
			
	while (document != null)
	{
        string itemsString = string.Empty;
		foreach (string itemName in itemNames)
		{
            string value = string.Empty;
			try
			{
				object[] valueArrey = document.GetItemValue(itemName);
				for (int icount = 0; icount < valueArrey.Length; icount++)
				{
					value += valueArrey[icount] == null ? string.Empty : valueArrey[icount].ToString() + ";###";
				}
			}
			catch
			{
				value = "N/A";
			}
			itemsString += value + ";;;###";
	   }

		document = view.GetNextDocument(document);

		metadata.Add(itemsString);
	}
	
	return metadata;
}

After getting the metadata it can be saved in a file and later processed for Notes-to-SharePoint migration.

Exporting Notes documents as RTF files

I had troubles exporting the document content as rich text file (RTF) using the .NET API for Notes. Its possible to export the text of the document which is stored in an item of type IT_TYPE.RICHTEXT but that doesn’t include the formatting nor the images of the documents. All what it returns is the plain text content of the document.
To export the document content as RTF I had to create an agent with Domino Designer. A great help was Rtftest.zip.
The agent loops through all the documents in a specified view and exports the documents as RTF. The resulting RTF files were not perfect (look and feel wise) but were very close to the original. Some of the problems I noticed were: Styling may not be the same 100 % as when viewed with Notes, some tables may be with no visible borders, and similar small problems. In any case the result was more than acceptable although the users had to inspect the documents quickly and make small changes after the files were converted to .docx files and uploaded to SharePoint.

Exporting Notes document’s embedded files (attachments)

There are two ways to export all the attachments from all Notes Documents in a view using LotusScript:

Using NotesRichTextNavigator

	Dim doc As NotesDocument
	Set doc = view.GetFirstDocument
	Dim title As String
	Do Until doc Is Nothing
		Dim body As NotesRichTextItem
		Set body = doc.GetFirstItem("YourDocBodyFieldName")

		Dim attachment As NotesEmbeddedObject
		Dim rtnav As NotesRichTextNavigator
		Set rtnav = body.CreateNavigator
		If rtnav.FindFirstElement(RTELEM_TYPE_FILEATTACHMENT) Then
			Do
				Set attachment = rtnav.GetElement()
				filepath$ = "C:\YourFolder\" & attachment.Source
				Call attachment.ExtractFile(filepath$)
			Loop While rtnav.FindNextElement()
		End If
		
		Set doc = view.GetNextDocument(doc)
	Loop

By getting EmbeddedObjects from NotesRichTextItem

	Dim doc As NotesDocument
	Set doc = view.GetFirstDocument
	Dim title As String
	Do Until doc Is Nothing
		Dim body As NotesRichTextItem
		Set body = doc.GetFirstItem("YourBodyFieldName")
		
		If Not Isempty (body.EmbeddedObjects) Then
			Forall att In body.EmbeddedObjects
				If att.Type = EMBED_ATTACHMENT Then
					filepath = "fullPathWhereToSaveTheFile"
					Call att.ExtractFile(filepath)
				End If
			End Forall
		End If
				
		Set doc = view.GetNextDocument(doc)
	Loop

This method with EmbeddedObjects is useful if you want to keep track which attachment belongs to which document. You can include that information in the filepath variable, or write a string with more information on the fly as the files are being extracted and than save it as a csv file.

Advertisements

4 Responses to Basic operations with Domino .NET API for export purposes

  1. Gustavo Leal says:

    Hi Naim, excelent post. I have a question: I am trying to get from body the sections (expandable) areas inside the body, do you know how to do it?, I am getting only plain text without the “header” for each section. Thanks in advance

    • Naim Murati says:

      Hi Gustavo,
      Are you doing that with Domino .NET API or with LotusScript? I use LotusScript for getting the content of the documents. Getting the body with Domino .NET API didn’t work because it gets only the plain text and parts of the structure of the documents were lost. I’ve heard Domino C API works better than .NET API for getting the body but I haven’t tested that. If you go with LotusScript than check Rtftest database (link in the post) and experiment by modifying it. I have not tested it with expandable sections.

      • Gustavo Leal says:

        Naim, thank you very much for your quickly response. Yes I’m using .NET API, then there is no much to do. I will try your suggestion and also try to test C API (I do not have exprience in C).

  2. Huber says:

    Great tutorial. And it helped me a lot.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: