Knoxville, TN

Creating SharePoint Workflows with WSPBuilder and WSS

July 11, 2008

As I mentioned in my previous post, WSPBuilder is a great tool for SharePoint development. Between its built-in commands and its project templates, it takes a lot of the hassle out of setting up SharePoint configuration files for your features and solutions.

However, it’s a little tricky to get it working for workflows, especially if you’re using Windows SharePoint Services instead of MOSS. Here’s what I eventually worked out:

  • Make sure you’re using the “WSPBuilder Project with Workflow” template for your project. I made this mistake this first time through, and nothing worked.
  • Remove references to Microsoft.Office.* Pull out the “ReceiverClass” and “ReceiverAssembly” references in feature.xml; you don’t need them anyway for a basic workflow. (If you do, you can always add them in later.)
  • Remove the AssociationUrl, InstantiationUrl, and ModificationUrl attributes from elements.xml. You’ll need to add them back in if you create forms for this workflow, but not for a basic workflow.

What’s SharePoint Good For?

March 26, 2008

In a previous post I discussed some of the trials and tribulations I’ve encountered with the mandate that we replace our current document management system with SharePoint. From the comments on that post, it sounds like pretty much everyone hates SharePoint to some extent.

Now, users, tend to hate anything that requires that they follow procedure or document their work, so it’s not entirely SharePoint’s fault. But some of it might be that SharePoint is being used for things it shouldn’t be used for. It’s a tool, and just like any other tool, it’s only good for certain situations. And even more to the point, it seems to have certain economies of scale as far as productivity goes.

Continue reading

Linking Membership to other tables

March 17, 2008

I ran into a very simple problem today that, unfortunately, had a somewhat complex solution. A user’s Active Directory login name had changed, and I needed to update his record in a web application which uses Membership to handle its logins.

Now, of course, the easiest way to uniquely identify your users is by username. You can easily get the ID of the currently logged in user from User.Identity.Name. Of course, as I discovered, this is a Bad Idea, because now I have to update 14 fields in 11 tables.

Instead, it’s best to user the ProviderUserKey property of the MembershipUser. This means it takes one extra step to get the current user’s ID: Membership.GetUser(User.Identity.Name).ProviderUserKey

On the other hand, you can pass the ProviderUserKey value into Membership.GetUser just like you did the username.

ASP.Net: URL Rewriting and Login forms

June 10, 2007

Here’s a quirk I’ve been stuck on for a while in the process of rewriting this site in ASP.Net, and just recently figured out a workaround for.

When you’re doing any sort of URL rewriting with Context.RewritePath, all of your pages post back to their actual URL instead of the URL that the user requested. While this is fine if you’re simply redirecting because you changed the name of a file, it’s not so nice if you’re actually using this as the basis for your content management system. Which I do.

First off, if you’re doing any sort of URL rewriting, check ScottGu’s blog post on the subject–pay particular attention to the “Handling ASP.Net Postbacks with URL Rewriting.” This will clear up most problems you have with forms on your pages.

There are, however, a few quirks with the Login and LoginStatus controls (used with ASP.Net 2.0’s built-in membership system) that this won’t fix.

To make a functional login button, capture the original URL before rewriting, and then set the Login control’s DestinationPageUrl property to the originally requested URL.

To make a functional logout button, capture the original URL before rewriting. Set the LoginStatus’ LogoutAction property to Redirect, and the LogoutPageUrl property to the original URL.

Here’s an example of how I did it:

if (!Context.User.Identity.IsAuthenticated)
{
    ((Login)LoginView1.FindControl("LoginForm1")).DestinationPageUrl = originalUrl;
    ((LinkButton)LoginView1.FindControl("LoginForm1").FindControl("LoginButton")).PostBackUrl = originalUrl;
}
else
{
    ((LoginStatus)LoginView1.FindControl("LoginStatus1")).LogoutPageUrl = originalUrl;
}

Fun (?) with Outlook RPC and Wildcard Extension Mappings

May 8, 2007

IIS, Outlook RPC, and things you just can’t test for.

Continue reading

Sorting a GridView Using ObjectDataSource, custom classes, and reflection, part 2

April 27, 2007

In part 1, I covered how to create an IComparer class that uses reflection to sort a list of objects based on a specified property name. While that’s the underlying mechanics that powers our GridView sorting solution, we still need a convenient way to hook it up to a GridView. And so, I extended the GridView class to create the ODSSortableGridView class that does just this.

Continue reading

Sorting a GridView Using ObjectDataSource, custom classes, and reflection, part 1

April 18, 2007

As I’ve mentioned before, I had to figure out early on the cleanest way of populating a GridView, and my choices were down to using TableAdapters/DataTables and business objects. While writing your own classes seems (to me, at least) to be the nicer way of structuring your program–if done right, it forces you to put all of the rules for handling data in its own tier–it gets a bit ugly when you have to hook up your custom classes to some of .NET’s built-in controls. Specifically, it starts getting to be a hassle once you realize that all the automagic goodness of GridView is a product of using the DataTable, and that sorting a list of objects on one member requires writing a whole new custom class per member. Maybe it’s the two and a half years of Python programming talking, but it seemed like there had to be a better way.

Continue reading

×