By Chris R. Chapman at November 11, 2009 14:42
Filed Under: .net, asp.net, better practices, moss, sharepoint, software development

A quick reminder:  Say you have a SharePoint Survey List in a site that you want to populate using a console application.  Further, say that said Survey List has an Event Receiver attached to it that needs to pick up settings from the web.config file for the host web app – let’s say a connection string.

You run your console application and notice that nothing is happening – well, something is happening, just not what you intended.  A quick look in the Event Log reveals a bizarre error indicating that an object reference isn’t instantiated and it appears to be originating several lines of code before you make a call to the ConfigurationManager thus:

_connectionString = ConfigurationManager.ConnectionStrings[SQL_CONNECTION_STRING_NAME].ConnectionString;

The line that that is generating the error has nothing whatsoever to do with this line.  It is a puzzling sort of puzzle.

You decide to check first principles and see if you can trigger the event receiver by hitting the list in the browser.  Yup:  Works fine.  So what gives?

Then you remember:  Your console app isn’t running in the same context as the browser app.  Of course it can’t find the <connectionStrings> element – it doesn’t exist as far as it’s concerned.  The called code in the Event Receiver is running blind!

<foreheadSlap> Simply add a {nameOfConsoleApp}.exe.config file local to the console .exe file and stash the configuration settings from the web.config that the called code needs to find. </foreheadSlap>

I knew this, you know.  I was just not thinking clearly while debugging.

By Chris R. Chapman at October 22, 2009 09:57
Filed Under: moss, wss30

While experimenting with some permission settings on a SharePoint Survey List this evening I made a rather nasty discovery:  Page separators and Edit Access permissions do not mix:

Spsurvey_1 

Allow me to explain:  I have a SharePoint Survey List that has sets of questions that I aggregate together using the Page Separator field type – this keeps the survey UI manageable for the user it is a bit lengthy (forty-seven questions in a mix of multi-choice and free text fields).  Not a big deal – well within the realm of what an OOTB Survey List is designed to handle.

However, a recent requirement surfaced during an iteration planning session to control edit access to submitted surveys – once a response is submitted, a user shouldn’t be able to go back and change it.  Again, this shouldn’t be a problem, I thought – just modify the Edit Access permissions for the list from the Advanced Settings (see above picture) and set to None.

And so it began:  When I logged in to the list as a regular user and responded to the survey, everything was going well on the first page:

Spsurvey_2

Then, I clicked Next…

Spsurvey_3

NO ACCESS FOR YOU, ADINAA!

What’s the issue?

In a word:  Permissions.  In many more words, a combination of permissions and the lifecycle for a SharePoint Survey List Item.

When a user first clicks Respond to this survey on the list, SharePoint creates a row for the new response record and fires the ItemAdding and ItemAdded events.  When the user then clicks on the Next button to move things along past the page separator to the next series of questions, SharePoint updates the record and fires the ItemUpdated event.  The only way you know whether a survey respondent has actually completed the survey and clicked Finish is by checking the list’s Completed field for a value of “1” (it’s “255” otherwise) while you’re in the ItemUpdated event handler.

It’s this event that the aforementioned permissions are gated against – when the list Edit Access permissions are set to None, any attempt by a non-admin user to “update” their record by clicking Next is met with an Access Denied response.  Change the settings back to Only their own, and the expected functionality is restored.

What’s the workaround?

Um – haven’t thought of one yet as this is really tied to how the Survey List behaves at a functional level.  In my case, the quick and dirty solution may be satisfied by another user story which describes closing off access to a survey once the Survey Closed Date has passed.  Initially, this will involve removing Contribute permissions on the list for non-admin users and restricting them to Read Only – but this still doesn’t solve the problem of editing submitted surveys prior to the close off date.

I may have a solution shortly, but for now I am noting this as a “known issue”.

 

By Chris R. Chapman at October 22, 2009 06:05
Filed Under: hacks, moss, software development, wss30

Earlier today, I was working on a custom survey list event receiver that ports results into a SQL database table when I noticed some peculiar behaviour:  Every time I added an entry to the survey, two duplicate rows were added to the SQL table.

Poking around the web, I see that this is indeed a common issue – David Birin captured the problem (and a solution) quite succintly on his blog in his January 2009 entry.  As he notes, the root of the problem is that if you have your event receiver deployed as a Feature (I did) and then create a template of a targeted list (you bet I did that) then the event receiver registrations are “baked in” to the template definition.

Now, when you create a list based on this template in a site that has the same event receiver Features enabled, you now are running each event handler twice.  As you repeat this process, you register more event receivers and things get out of hand geometrically.

NOT GOOD.

A Hack for a Solution

David’s solution is to add in some custom code that loops through the event receivers and deletes them individually.  While this is robust for future-proofing, I wanted an easier way so that I could get back to coding.  Here’s what I did:

  1. First, I went to the List Template Gallery for my Site Collection and saved the offending list template to my C:\ drive and renamed the extension from “.stp” to “.cab”
  2. Next, I opened up the .cab file and extracted the manifest.xml file within and tossed it into Visual Studio where I cleaned it up with an Edit -> Advanced -> Format Document
  3. I located the <Receivers> element and removed each <Receiver> child element.
  4. I changed the <TemplateTitle> to reflect the new version, eg. “My Survey V4”
  5. I made similar changes to the <Form> and <WebPart> element URL attributes, eg. “Lists/My Survey V4/DispForm.aspx”
  6. Next, I saved this file and then used MAKECAB.EXE to package it up (comes with the Windows SDK) and renamed the extension from “.cab” to “.stp”
  7. I opened up a browser on my test server, navigated to the List Template Gallery and uploaded my revised template and created a list from it.
  8. Presto!  The ItemAdded event was only firing once as it should.

Hope this helps anyone encountering the same issue – it’s a quick-fix which helps avoid the ground-zero for the issue which is building a template of a list while the event receiver feature that targets that list is enabled.

By Chris R. Chapman at June 20, 2009 00:51
Filed Under: Announcement, moss, sharepoint

I’ve been away from this blog for several long months for some “good” reasons:

  • Busy, busy, busy.  From February to just recently, I’ve been working on some demanding projects (in the sense of time, not intellect) in my role as an MCS consultant with Microsoft;
  • Loss of my technical “muse” – I’ve seen… stuff, man.  And it wasn’t pretty.
  • Nothing exceptional to write about given the first two points.

So why return?  To get back into the groove and find my muse once more – if she exists!  First, some housekeeping notes:

For Recruiters/Headhunters:

  • Thank you for downloading my resume (which I know is out-of-date) and for contacting me from around the world (I’m thinking especially of the guys from Ireland, the UK, USA and yes, you too India!);
  • Please note that I am currently employed as a SharePoint Consultant with Microsoft Consulting Services Canada (MCS), and for all the warts, it really is a good gig that I’m not likely to give up any time soon;
  • Also, while I do thank you for your interest, my days of gambling a low salary for stock options in a “startup” are well-past me – I’m flattered, and I’d love to help, but really:  I’ve worked enough Bataan Death March projects to last a lifetime.

For Everyone Else:

  • I’m going to start cranking out some writings based on my recent SharePoint projects, which will include channelling an old acqaintance, SharePoint MVP Paul Culmsee, about what I’m seeing in organizations who are deploying SharePoint and why, despite the best of intentions and lots of dollars, are setting themselves up for failure.  The corollary to this, of course, is what you can do to avoid similar pitfalls.
  • I’m also going to, where I can, begin writing about what’s coming for the next release of SharePoint, Microsoft’s excellent Software + Services strategy (which moves the flagship products into the cloud and offering them on a subscription basis), and how you can ensure that your existing deployments can move smoothly when the time comes.

Stay tuned.

By Chris R. Chapman at January 23, 2009 06:01
Filed Under: moss, sharepoint

It seems that SharePoint 2007 is enjoying a mini-Renaissance right now thanks to innovative client-side “hacks” using the lightweight, open source Javascript library, jQuery.  jQuery’s strength and popularity is built on how incredibly easy it is to use to manipulate DOM elements with very few lines of code.

For example, take a look over at EndUserSharePoint: Paul Grenier has released a whack of posts on how to add some cool features to SharePoint using jQuery:

So, inspired by Paul’s great work, here’s my offering on how to mod-up the SharePoint wiki toolbar with your own links or controls using jQuery:

Jquery_custom_wiki_link

This is really easy to pull off:

  1. First, visit the jQuery website and get the minimized (ie. compressed) version of the library – i’m using version 1.3 here.  Store this in a document library within the site or wherever it is easy to access.
  2. Add a Content Editor Web Part (CEWP) to the bottom of the page by opening it in Edit Mode (Site Actions menu); open the Modify Settings tool pane and from this, the Source Editor.
  3. Paste in the following code:

    <script src="https://your.sharepoint.site/Scripts/jquery-1.3.min.js" type="text/javascript"></script>

    <script type="text/javascript">

     

    // Wait for the DOM to load before we execute...

    $(function() {

     

     // make copies of the layout cells for the wiki toolbar

     var $tdSeparator = $("table.ms-wikitoolbar tbody tr td.ms-separator:first").clone();

     var $tdToolbar = $("table.ms-wikitoolbar tbody tr td.ms-toolbar:first").clone();

     var $tdLastCell = $("table.ms-wikitoolbar tbody tr td.ms-toolbar[width]:last").clone();

     var $parent = $("table.ms-wikitoolbar tbody tr td.ms-toolbar[width]:last").parent();

     

     // remove the last TD element (padding)

     $("table.ms-wikitoolbar tbody tr td.ms-toolbar[width]:last").remove();

     

     // now build a link

     var $select = "<a href='#' class='ms-toolbar'>Wiki Pages<a>";

     

     // add a separator pipe, append the link and then the padding

     $parent.append($tdSeparator).append("<td class='ms-toolbar' nowrap>" +

       $select + "</td>").append($tdLastCell);

     

    });

     

    </script>

  4. Save and close!

As you can see, this is a really low-cost way to modify the SharePoint UI:  There’s no hassling with the .aspx layout page in the ‘12’ hive, no messing about with SharePoint Designer – just some simple Javascript, and even then it’s minimal.

Now, I do imagine if you’ve no prior experience with jQuery you may be wondering what the hell is going on up there – the best way to think of it is akin to regular expressions – it’s all about walking the DOM and finding what you want to modify.  jQuery’s notation makes this easy to accomplish and masks a lot of the complexity/verbosity of equivalent lines of code.  This said, you may want to look over Paul’s examples and the jQuery online documentation to get a handle on how to use it.

Enjoy…

Tags:

About Me

I am a Toronto-based software consultant specializing in SharePoint, .NET technologies and agile/iterative/lean software project management practices.

I am also a former Microsoft Consulting Services (MCS) Consultant with experience providing enterprise customers with subject matter expertise for planning and deploying SharePoint as well as .NET application development best practices.  I am MCAD certified (2006) and earned my Professional Scrum Master I certification in late September 2010, having previously earned my Certified Scrum Master certification in 2006. (What's the difference?)