Tech in the 603, The Granite State Hacker

Getting Display Names from User Names in a hostile SharePoint environment

I recently ran into a nasty situation where I needed a reliable way to get a list of user Full Names (or Display Names) from a list of usernames in a SharePoint process.

The short answer was easy…  The code runs server side so…

SPUser theUser = web.EnsureUser(username);
string DisplayName = theUser.Name;

//Right?

Well, under normal circumstances, sure.  

In this circumstance, I was checking a list of lists of user names, a condition where I might need to check hundreds of items, each of which could have a list of users to check.

No biggie, just add a lookup table and cache the results over multiple calls so that I only ever have to look a user up once in my process.

Now here’s the real kicker.  In my target environment, EnsureUser comes back instantly if the username is a valid, active user in Active Directory.  If the user is not a valid user?   The command takes over 40 seconds per call to fail!

My solution was two-fold.  

1)  use the aforementioned cache strategy, which I have in my sample code below as _nameMap.
2)  Use a simple worker thread.  Give it two seconds to succeed.  Kill the thread if it takes longer than that for any reason.

I initially made the mistake of using SPContext.Current.Web in the thread, but that can *sometimes* produce a threading violation.   The code below creates a whole new instance of SPSite/SPWeb on every pass, but that’s a lot safer and better performing than a lot of alternatives.

private Dictionary _nameMap = new Dictionary();  

private string GetUsersWithTempCacheAndTimeoutEnforcement(string rawUsers)
{
string result = string.Empty;
SPContext.Current.Web.AllowUnsafeUpdates = true;
foreach (string aUser in rawUsers.Split(';'))
{
try
{
string addUser = string.Empty;
string checkUser = aUser.Split('#')[1];
if (checkUser.Contains("\\"))
{
lock (_nameMap)
{
if (_nameMap.ContainsKey(checkUser))
{
addUser = _nameMap[checkUser] + "; ";
}
else
{
SPUser userResult = null;
SPContext context = SPContext.Current;
string webUrl = context.Web.Url;

System.Threading.ThreadStart st = new System.Threading.ThreadStart(
() =>
{
try
{
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
userResult = web.EnsureUser(checkUser);
}
}
}
catch (Exception)
{ }
});
System.Threading.Thread workThread = new System.Threading.Thread(st);
workThread.Start();
workThread.Join(2000);
if (workThread.IsAlive)
{
workThread.Abort();

}
if (userResult == null)
{
_nameMap[checkUser] = checkUser;
addUser = checkUser + "; ";
}
else
{
_nameMap[checkUser] = userResult.Name;
addUser = userResult.Name + "; ";
}
}
}
}
result += addUser;
}
catch (IndexOutOfRangeException)
{
}
catch (Exception ex)
{
}
}
return result;
}

Tech in the 603, The Granite State Hacker

Time to Remodel the Kitchen?

A few good reasons to consider keeping your IT infrastructure up to snuff…

http://edgewatertech.wordpress.com/2012/08/21/time-to-remodel-the-kitchen/

(I’m honored to have the post accepted & published on Edgewater’s blog.)  🙂 

Tech in the 603, The Granite State Hacker

Windows Phone Live Tiles… What’s happening right now?

The first thing you see when you see a Windows Phone is the start display.  In fact, it’s so distinct, that it becomes the most identifiable feature of a Windows Phone at a distance.  Typically, the start display is populated with a number of application icons…  only on Windows Phone (and Metro) they’re all square or rectangles and are called Tiles.  

On second glance, you start to notice that many of these tiles have some form of light animation to them, typically communicating basic information.  The Tiles that open messaging apps indicate the number of new messages, for example.

When I first started playing with my Windows Phone, the live tiles seemed like a nifty gimmick… important for messaging features, but not really useful for anything else.

As I’ve dug in on app development for Windows Phone, I’ve come to see the Live Tiles as a really under-leveraged feature, communicating with users on a level that previously couldn’t be achieved.  They’re terribly simple, but terribly engaging.  I now see that they are the addictive component of Facebook’s classic “What’s on your mind?” status updates… statuses provided by the apps on your phone. 

In some cases, this literally translates to status update from your friends, since Tiles can be put on your start display for any contact.  (Since contacts are linked via the People Hub to their Facebook, Twitter, and Linked In…  voila!  one tile gets status updates for that individual covering all the bases.)

What’s really cool is that, like I said before, getting status updates is not limited to contacts.  I’ve got apps that have live tiles that… display current weather conditions including radar maps.  …show stock quotes & notifications.  …display photos from various sources.  … even shows your XBox avatar fully animated.

I’m in the process of adding a new feature to my hobby project, Jimmy Sudoku, to make use of live tiles to show the progress of the “current” puzzle.  

A new hobby project I’m working on has to do with the Granite State (NH) SharePoint Users Group that I am a principal organizer of.   This app will eventually be a hub for group information, offering member users easy access to schedules, speaker info, weather delay notifications, registration info, and even Power Point presentation slides.   Interestingly enough, a key feature will be to provide a live tile which will poll a webservice to get updates… the live tile will then let the user know they have important information to review, thus engaging the user.  (Sure, push technology’s available, but in this case, polling will be sufficient.)

The uses for this being able to re-engage a user after they’ve “quit” the application itself are significant.   I can easily imagine a time when the marketing significance of them makes building Windows Phone apps far more attractive to companies than iPhone or Droid apps.  Even if companies aren’t trying to hock a specific product…  imagine corporate “investor information” apps, for example, that provide easily accessible information about a company… but most importantly, providing “status updates” to investors to re-engage interest.

I’ll admit, at some level, this reminds me of electronic kids toys that attempt to re-engage kids in play after the kid has put it down and walked away by flashing a few lights & making a little noise.  There’s reasons those kids toys do that, though, and anyone paying attention with a mind for marketing will get what they are.

This is another Non-App for Windows Phone… one of the many cool features built into the device in an accessible, but non-cluttering way… and another reason I keep seeing Windows Phone as the IBM Compatible of smart phones.

So the above is why you want Live Tiles…   Here’s a code snippet that illustrates how:

using Microsoft.Phone.Shell;

… 

public static void UpdateAppTile(JimmySudoku4.Puzzles.SudokuState state)

{
    ShellTile appTile = ShellTile.ActiveTiles.First();

    if (appTile != null)
    {
        StandardTileData data;
        if (state.GetElapsedTime().Ticks == 0)
        {
            data = new StandardTileData()
                {
                    BackContent = “Game Complete”,
                    BackTitle = “Try again!”, Count = 0
                };
        }
        else
        {
            int completeCellCount =
                state.MasterList.Where(c => c.Value != 0).Count();
            int percent = (int)((decimal)((decimal)completeCellCount / (decimal)81)
                * (decimal)100);
            if (percent < 100)
            {

                data = new StandardTileData()
                    {
                      BackContent =
                            string.Format(“Elapsed Time:\n{0:hh:mm:ss}”,
                                 state.GetElapsedTime()),
                        BackTitle = string.Format(“{0}% complete”, percent)
                    };
            }
            else
            {
                data = new StandardTileData()
                    {
                        BackContent = string.Format(“Completion Time:\n{0:hh:mm:ss}”,
                            state.GetElapsedTime()),
                        BackTitle = “You Won!”
                    };
            }
        }

        appTile.Update(data);
    }
}

Tech in the 603, The Granite State Hacker

Anonymous Form Submission to Form Library with InfoPath in MOSS

Here’s a bit of a trick I ran across while helping to develop some MOSS2007 solutions.

I needed to configure InfoPath so that it could submit documents to a site that the submitter would not be able to access. In SharePoint, this is not directly possible.

A common work-around is to set up incoming email for the target list, and submit by email to that. Unfortunately, my client is part-way through a Notes to Exchange migration, so this wasn’t practical in the given time frame.

The solution… create two sites, one that is accessible to the submitter, and the other that is not. On the accessible site, create a new, “hidden” list that the user can submit to. Add an event receiver to that list, such that whenever a new item is added, the item is moved to the real intended target using elevated privileges.

Using VSeWSS extensions, create a List Definition project that has something like this in the ItemEventReciever.cs file:

 

using System;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using VSeWSS;

namespace AutoForwardingFormLibrary
{
[CLSCompliant(false)]
[TargetList("38aea319-af78-4489-9059-d124c68bf9fe")]
[Guid("9d0f139b-d9ed-4b6c-b0ba-2353cb3bad85")]
public class AutoForwardingFormLibraryItemEventReceiver : SPItemEventReceiver
{
private SPListItem addedItem = null;

///
/// Initializes a new instance of the Microsoft.SharePoint.SPItemEventReceiver class.
///

public AutoForwardingFormLibraryItemEventReceiver()
{
}

///
/// Asynchronous after event that occurs after a new item has been added to its containing object.
///

///
/// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
///
public override void ItemAdded(SPItemEventProperties properties)
{
addedItem = properties.ListItem;
if (addedItem == null)
{
throw new ArgumentNullException("properties.ListItem");
}
SPSecurity.CodeToRunElevated moveItem = moveItem_Elevated;
SPSecurity.RunWithElevatedPrivileges(moveItem_Elevated);
}

private void moveItem_Elevated()
{
addedItem.CopyTo(SPUrlUtility.CombineUrl("http://targetserver/sites/jimw/docs/formlibrary", addedItem.Name));
addedItem.Delete();
}
}
}


Tech in the 603, The Granite State Hacker

Application Platform Infrastructure Optimization

In doing some research for a client on workflow in SharePoint, I came across this interesting article about the differences between BizTalk 2006 and the .NET Workflow Foundation (WF).

The article itself was worth the read for its main point, but I was also interested in Microsoft’s Application Platform Infrastructure Optimization (“APIO”) model.

The “dynamic” level of the APIO model describes the kind of system that I believe the .NET platform has been aiming at since 3.0.

I’ve been eyeing the tools… between MS’s initiatives, my co-workers’ project abstracts, and the types of work that’s coming down the pike in consulting. From the timing of MS’s releases, and the feature sets thereof, I should have known that the webinars they’ve released on the topic have been around for just over a year.

This also plays into Microsoft Oslo. I have suspected that Windows Workflow Foundation, or some derivative thereof, is at the heart of the modeling paradigm that Oslo is based on.

All this stuff feeds into a hypothesis I’ve mentioned before that I call “metaware”, a metadata layer on top of software. I think it’s a different shade of good old CASE… because, as we all know… “CASE is dead… Long live CASE!”

Tech in the 603, The Granite State Hacker

If It Looks Like Crap…

It never ceases to amaze me what a difference “presentation” makes.

Pizza Hut is airing a commercial around here about their “Tuscani” menu. In the commercial, they show people doing the old “Surprise! Your coffee is Folgers Crystals!” trick in a fancy restaurant, except they’re serving Pizza Hut food in an “Olive Garden”-style venue.

It clearly shows my point, and that the point applies to anything… books, food, appliances, vehicles, and software, just to name the first few things that pop to mind. You can have the greatest product in the world… it exceeds expectations in every functional way… but any adjective that is instantly applied to the visual presentation (including the environment it’s presented in) will be applied to the content.

If it looks like crap, that’s what people will think of it.

(Of course, there are two sides to the coin… What really kills me are the times when a really polished application really IS crap… it’s UI is very appealing, but not thought out. It crashes at every click. But it looks BEAUTIFUL. And so people love it, at least enough to be sucked into buying it.)

Good engineers don’t go for the adage “It’s better to look good than to be good.” We know far better than that. You can’t judge the power of a car by its steering wheel. Granite countertops look great, but they’re typically hard to keep sanitary.

When it comes to application user interfaces, engineers tend to make it function great… it gives you the ability to control every nuance of the solution without allowing invalid input… but if it looks kludgy, cheap, complex, or gives hard-to-resolve error messages, you get those adjectives applied to the whole system.

So what I’m talking about, really, is a risk… and it’s a significant risk to any project. For that reason, appearance litterally becomes a business risk.

For any non-trivial application, a significant risk is end-user rejection. The application can do exactly what it’s designed to do, but if it is not presented well in the UI, the user will typically tend to reject the application sumarily.

That’s one thing that I was always happy about with the ISIS project. (I’ve blogged about our use of XAML and WPF tools in it, before.) The project was solid, AND it presented well. Part of it was that the users loved the interface. Using Windows Presentation Foundation, it was easy to add just enough chrome to impress the customers without adding undo complexity.

Tech in the 603, The Granite State Hacker

Jimmy SuDoku 3.0 Released

Those of you who have worked with me on a project in the past few years probably know of my hobby project. It’s an implementation of SuDoku. It’s made for Windows Mobile devices (cell phones, etc.), but it also runs on Windows XP (et al).

The old version, 2.5, had been published on PocketGear. This last update was published in January, 2007, just before I started with Edgewater.

I’ve been hacking at it here & there since then, but the project suffered from lots of maladies… most significantly lack of time.

So after more than a year and a half, I’m happy to finally announce Jimmy SuDoku 3.0!

3.0 has a whole new game state model, based on CLR classes rather than an XML DOM. This means the puzzle generator’s fast enough on hand-held devices that it doesn’t need a web service to do the work for it. Another side-effect of this change is a smaller run-time memory footprint, though I’m not sure by exactly how much.

I also figured out how to leverage the hardware controls on WM6.0 & 6.1 devices so that non-touchscreen devices can play, too.

Tech in the 603, The Granite State Hacker

SSIS: Unit Testing

I’ve spent the past couple days putting together unit tests for SSIS packages. It’s not as easy to do as it is to write unit & integration tests for, say, typical C# projects.

SSIS Data flows can be really complex. Worse, you really can’t execute portions of a single data flow separately and get meaninful results.

Further, one of the key features of SSIS is the fact that the built-in data flow toolbox items can be equated to framework functionality. There’s not so much value in unit testing the framework.

Excuses come easy, but really, unit testing in SSIS is not impossible…

So meaningful unit testing of SSIS packages really comes down to testing of Executables in a control flow, and particularly executables with a high degree of programability. The two most significant control flow executable types are Script Task executables and Data Flow executables.

Ultimately, the solution to SSIS unit testing becomes package execution automation.

There are a certain number of things you have to do before you can start writing C# to test your scripts and data flows, though. I’ll go through my experience with it, so far.

In order to automate SSIS package execution for unit testing, you must have Visual Studio 2005 (or greater) with the language of your choice installed (I chose C#).

Interestingly, while you can develop and debug SSIS in the Business Intelligence Development System (BIDS, a subset of Visual Studio), you cannot execute SSIS packages from C# without SQL Server 2005 Developer or Enterprise edition installed (“go Microsoft!”).

Another important caveat… you CAN have your unit test project in the same solution as your SSIS project. Due to over-excessive design time validation of SSIS packages, you can’t effectively execute the SSIS packages from your unit test code if you have the SSIS project loaded at the same time. I’ve found that the only way I can safely run my unit tests is to “Unload Project” on the SSIS project before attempting to execute the unit test host app. Even then, Visual Studio occassionally holds locks on files that force me to close and re-open Visual Studio in order to release them.

Anyway, I chose to use a console application as the host app. There’s some info out there on the ‘net about how to configure a .config file borrowing from dtexec.exe.config, the SSIS command line utility, but I didn’t see anything special in there that I had to include.

The only reference you need to add to your project is a ref to Microsoft.SqlServer.ManagedDTS. The core namespace you’ll need is

using Microsoft.SqlServer.Dts.Runtime;

In my first case, most of my unit testing is variations on a single input file. The package validates the input and produces three outputs: a table that contains source records which have passed validation, a flat output file that contains source records that failed validation, and a target table that contains transformed results.

What I ended up doing was creating a very small framework that allowed me to declare a test and some metadata about it. The metadata associates a group of resources that include a test input, and the three baseline outputs by a common URN. Once I have my input and baselines established, I can circumvent downloading the “real” source file, inject my test source into the process, and compare the results with my baselines.

Here’s an example Unit test of a Validation executable within my SSIS package:

[TestInfo(Name = "Unit: Validate Source, duplicated line in source", TestURN = "Dupes")]
public void ValidationUnitDupeLineTest()
{
using (Package thePackage = _dtsApp.LoadPackage(packageFilePath, this))
{
thePackage.DelayValidation = true;
DisableAllExecutables(thePackage);
EnableValidationExecutable(thePackage);
InjectBaselineSource(GetBaselineResource("Stage_1_Source_" + TestURN), thePackage.Variables["SourceFilePath"]);
thePackage.Execute(null, null, this, null, null);
string errorFilePath = thePackage.Variables["ErrorLogFilePath"].Value as string;
//throw new AbortTestingException();
AssertPackageExecutionResult(thePackage, DTSExecResult.Failure);
AssertBaselineAdjustSource(TestURN);
AssertBaselineFile(GetBaselineResourceString("Baseline_Stage1_" + TestURN), errorFilePath);
}
}

Here’s the code that does some of the SSIS Package manipulation referenced above:


#region Utilities
protected virtual void DisableAllExecutables(Package thePackage)
{
Sequence aContainer = thePackage.Executables["Adjustments, Stage 1"] as Sequence;
(aContainer.Executables["Download Source From SharePoint"] as TaskHost).Disable = true;
(aContainer.Executables["Prep Target Tables"] as TaskHost).Disable = true;
(aContainer.Executables["Validate Source Data"] as TaskHost).Disable = true;
(aContainer.Executables["Process Source Data"] as TaskHost).Disable = true;
(aContainer.Executables["Source Validation Failure Sequence"] as Sequence).Disable = true;
(aContainer.Executables["Execute Report Subscription"] as TaskHost).Disable = true;
(thePackage.Executables["Package Success Sequence"] as Sequence).Disable = true;
(thePackage.Executables["Package Failure Sequence"] as Sequence).Disable = true;
}


protected virtual void DisableDownloadExecutable(Package thePackage)
{
Sequence aContainer = thePackage.Executables["Adjustments, Stage 1"] as Sequence;
TaskHost dLScriptTask = aContainer.Executables["Download Source From SharePoint"] as TaskHost;
dLScriptTask.Disable = true;
}


protected virtual void EnableValidationExecutable(Package thePackage)
{
Sequence aContainer = thePackage.Executables["Adjustments, Stage 1"] as Sequence;
TaskHost validationFlow = aContainer.Executables["Validate Source Data"] as TaskHost;
validationFlow.Disable = false;
}

protected virtual void EnableValidationExecutable(Package thePackage)
{
Sequence aContainer = thePackage.Executables["Adjustments, Stage 1"] as Sequence;
TaskHost validationFlow = aContainer.Executables["Validate Source Data"] as TaskHost;
validationFlow.Disable = false;
}

Another really handy thing to be aware of…

IDTSEvents

I highly recommend you implement this interface and pass it into your packages. Of course, in each event handler in the interface, implement code to send reasonable information to an output stream. Notice the call to thePackage.Execute, way up in the first code snippet… the class that contains that method implements that interface, so I can manipulate (when necessary) how to handle certain events.

Interestingly, I haven’t needed to do anything fancy with that so far, but I can imagine that functionality being very important in future unit tests that I write.

Here’s a visual on all the resources… the image shows SSMS over VS, with both database tables and project resources with common URNs to relate them.

I won’t get into the details of the framework functionality, but I found it useful to be able to do things like set a flag to rebuild baseline resources from current outputs, and such.

I modeled some of my framework (very loosely) functionality on the Visual Studio Team System Edition for Testers, which we used on the TWM ISIS project.

Another interesting lesson learned: I can see that the folks who built SSIS were not avid unit testers themselves. SSIS Executables have a “Validate()” method. I encountered lots of problems when I tried to use it. Hangs, intermittent errors, all that stuff that testing should have ironed out.