Header Image -

Traversing a SP hierarchy in C#

by dave 0 Comments

Standard disclaimer – the ‘migratenotes’ posts come from a Notes Migration blog that I wrote from 2007-2010.  More Info

——-

At the risk of being mocked for my lacking C# skillz, I thought I’d post another code snippet.
(And at the risk of losing traffic, because it seems that whenever I post code, Google stops sending me traffic for a couple days.)

One thing we have encountered as part of our migration is the need to make a change to an entire environment. (Modifying ACLs, etc.) In Notes, AdminP can do some of this for you, but when the change needs some calculated logic, you need to script it. Notes has the NotesDbDirectory object which handles this nicely for you.

But it got me thinking – what if you wanted to traverse your entire SharePoint environment? What would that code look like? So I sat down this morning, and spit out the code below.
It is just a recursive call to each site’s subsites, which gives you an opportunity to do something at each site.

static void Main(string[] args)

{

SPSite rootSite = new SPSite(”http://yourserver”);

SPWeb site;

SPWebCollection children; site = rootSite.OpenWeb();

DoYourStuff(site);

//Traverse SP hierarchy

children = site.GetSubwebsForCurrentUser();

if (children.Count > 0)

{

ProcessChildren(children);

}

}

static void ProcessChildren(SPWebCollection sites)

{

foreach (SPWeb site in sites)

{

DoYourStuff(site);

SPWebCollection children;

children = site.GetSubwebsForCurrentUser();

if (children.Count > 0)

{

ProcessChildren(children);

}

}

}

Why Notes shops don’t match up to Microsoft’s recommendations

by dave 0 Comments

Standard disclaimer – the ‘migratenotes’ posts come from a Notes Migration blog that I wrote from 2007-2010.  More Info

——-

Once again, comments and emails have given me some insight into questions and false assumptions that some Notes people may have.

Namely, they assume that the recommendations given by Microsoft partners will apply to a Notes migration. And while certainly much of their technical advice is valid, the underlying viewpoint of a Microsoft partner is going to miss an extremely important piece of information about a Notes shop:

The current collaboration in a Notes shop is NOT based around Microsoft Office. Notes people do not email spreadsheets back and forth. They do not use Access databases, or share documents via email. They already have a collaboration infrastructure in place, and are not starting from scratch.

Sharepoint was designed to give organizations their first stab at collaboration. Its primary strength is to take Office documents, and share them on the web. While I am sure this is a great help to many organizations, as a Notes professional, it just doesn’t impress me that much.. SharePoint is an immature product. It has flaws and weaknesses, and we have already addressed some of them on this blog.

But those weaknesses get exaggerated when we go out deliberately looking for flaws, and this type of exaggeration is exactly what I want to avoid here. Let’s call out the weaknesses, but lets not spin SharePoint’s faults into something worse than it really is.

With that in mind, lets talk about MOSS. MOSS is the “Microsoft Office SharePoint Server.” It adds functionality to SharePoint. But not as much as people think. the plain old freebie SharePoint install is what gives you most of the programmability of SharePoint. And because a Notes shop is already used to doing a certain level of development for their apps, that is the level of complexity that most Notes shops really need.

So when you see lists of the technologies from Microsoft that you must install and learn to run a SharePoint environment, take them with a grain of salt. Maybe in the future, your organization will reach that level of complexity. But to start a migration, you really just need a few things, most of which you probably already have:

  • Web Server (IIS/ASP.NET, with SharePoint services installed)
  • SQL Server  (technically optional, but realistically you need it to have any scalability.)
  • Exchange Server (and even this is optional)
  • Backups for the above.

What I am finding is that because SharePoint has limitations and weakness on its programmability, most Notes professionals do not accept its built-in functionality. So they step down into C#, and write custom .NET code. And while people will tell you that this is much harder than using the rest of the Microsoft platform, it greatly simplifies your infrastructure needs. (Not to mention costs.)

Again – as your Microsoft platform grows, you probably will add on more tools and end up with a more complex infrastructure. But the assumption  that it takes a  ton of effort to get going on SharePoint just isn’t correct.

What should not migrate?

by dave 0 Comments

Standard disclaimer – the ‘migratenotes’ posts come from a Notes Migration blog that I wrote from 2007-2010.  More Info

——-

A question has indirectly risen, both in online and offline conversations, of how we would define which applications should NOT be migrated to a new platform. Assuming that a small subset of Notes functionality will remain in the organization, what features or functions would lead you to  not even attempt a migration?

My answer would be the following:

1) Any application that truly needs offline access, and therefore replication. In my particular organization, surprisingly, nothing fits this category.
2) Any app that requires field-level encryption. The other granular levels of Notes security can be emulated with some skilled development efforts, although I acknowledge they are more difficult in Microsoft technologies. But I know of no way to set encryption on individual fields other than through the use of the Notes  client.
3) Any app that is business critical, directly generates the revenue for the company, and also well-loved by the business users. An app that works, that makes the money, and that isn’t a source of pain for people…. it should just be left alone to do its job.

Code: Updating yesterday’s code

by dave 0 Comments

Standard disclaimer – the ‘migratenotes’ posts come from a Notes Migration blog that I wrote from 2007-2010.  More Info

——-

Yesterday I posted some code, and some reasons why it wasn’t quite useful yet.
So this morning, I fixed my main two complaints by adding checks to see if the list already exists before creating it, and adding a check for an existing record before creating it. This could now be scheduled nightly, and will maintain your SharePoint version of a Notes catalog for you.
You would, of course, need to create some views to make the resulting list user-friendly. Maybe I’ll tackle that another day, too. But that can be done easily through the browser interface, so it isn’t a high priority on my list.

I included the full program code, as I realized some of the objects wouldn’t be resolved correctly in the IDE unless you saw my ‘using’ statements.

One question, though – I did not find any method in the SharePoint API to check for the existence of a list by using that list’s name. I used a try/catch block instead. Do any SharePoint folks know if that is appropriate, or is there a better method?

On with the updated code:
(Disclaimer – untested code, but it should do the trick.)

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Microsoft.SharePoint;
using Domino;

namespace NotesInventory
{
class Program
{
static void Main(string[] args)
{
SPSite rootSite = new SPSite(”http://localhost“);
SPWeb site = rootSite.OpenWeb();
SPList l;
SPListItem li;
StringCollection sc;
StringBuilder q;
SPQuery sq = new SPQuery();
SPListItemCollection items;

try //to get the list
{
l = site.Lists[”Notes Inventory”];
}
catch (Exception ex)
{ // it isn’t there — make it
Guid newGuid = site.Lists.Add(”Notes Inventory”, “List of Notes Applications”, SPListTemplateType.GenericList);
l = site.Lists.GetList(newGuid, false);

l.Fields.Add(”DB Path”, SPFieldType.Text, true);
l.Fields.Add(”Business Owner”, SPFieldType.Text, false);
sc = new StringCollection();
sc.AddRange(new string[] { “SharePoint”, “Exchange Mailbox”, “InfoPath”, “Domino Web UI”, “.NET Development”, “3rd Party Tool”, “Decommission”, “No Action” });
l.Fields.Add(”Migration Plan”, SPFieldType.Choice, false, true, sc);
sc = new StringCollection();
sc.AddRange(new string[] { “< 10 Hours”, “10-50 Hours”, “50-150 Hours”, “150-300 Hours”, ” >300 Hours” });
l.Fields.Add(”Scope”, SPFieldType.Choice, false, true, sc);
l.Fields.Add(”Priority”, SPFieldType.Number, false);

}
//OK, we’ve now got a list — let’s fill it with Notes Data.
NotesSession s = new NotesSession();
s.Initialize(”password”);
NotesDbDirectory dbdir =s.GetDbDirectory(”server”);
NotesDatabase db = dbdir.GetFirstDatabase(DB_TYPES.NOTES_DATABASE);

while (db != null) {
try
{
db.Open();

//check to see if record exists
q = new StringBuilder();
q.Append(”<Where>”);
q.Append(”<Eq><FieldRef Name=‘DB Path’ />”);
q.Append(”<Value Type=‘String’>”);
q.Append(db.FilePath);
q.Append(”</Value></Eq>”);
q.Append(”</Where>”);

sq.Query = q.ToString();
items = l.GetItems(sq);

if (items.Count == 0) { //no record found — create it
li = l.Items.Add();
li[”Title”] = db.Title;
li[”DB Path”] = db.FilePath;
li.Update();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
db = dbdir.GetNextDatabase();
}
}
}
}