Central Ohio Day of .Net 2010 Slides and Files

    This weekend I presented my “The Power of PowerShell + SharePoint 2007” session at the Central Ohio Day of .Net conference in Wilmington, OH.  This is the second year I’ve attended this conference, first time as a presenter.  For those unfamiliar Day of .Net conferences are a one-day conference on all things .NET organized by developers for developers.  These events are usually offered at no cost to anyone interested in .NET development.

    The attendees of my session had some great questions and I hope they all got something worthwhile out of it.  Below are my slides and demo scripts (some of which I didn’t have time to demo) along with my sample profiles.  If you have any questions, comments, or feedback feel free to leave comments here or send me an email at brian.jackett@gmail.com.

 

Slides and Files

SkyDrive link

 

Technology and Friends Interview Experience

    On a side note, any of you familiar with one of my Sogeti co-workers in Detroit David Giard may know that he hosts a web series called Technology and Friends.  After my session David tracked me down and asked to interview me about PowerShell.  I was happy to oblige so we sat down and taped some material.  I don’t know when that interview will be going live, but look for it on www.davidgiard.com.

 

Conclusion

    A big thanks goes out to all of the sponsors, speakers, and attendees for the Central Ohio Day of .Net conference.  Without all of them this conference couldn’t have been possible.  I had a great time at the conference and look forward to coming back next year whether that is as a speaker or attendee.

      -Frog Out

Slides and Files from Day of .Net Ann Arbor ‘10

    This past Saturday I presented “Real World Deployment of SharePoint 2007 Solutions” at the Ann Arbor Day of .Net conference in Ann Arbor, MI.  Below are my slides and PowerShell demo scripts I used during the presentation.  Thanks to everyone who attended my session, as well as the sponsors, speakers, organizers and all attendees who made this event happen.

 

Slides and demo scripts

Be Careful When Referencing SPList.Items

BeCarefulSafe

Be very careful how you reference your SPListItem objects through the SharePoint API.  I’ll say it again.  Be very careful how you reference your SPListItem objects through the SharePoint API.  Ok, now that you get the point that this will be a “learn from my mistakes and don’t do unsmart things like I did” post, let’s dig into what it was that I did poorly.

Scenario

For the past year I’ve been building custom .Net applications that are hosted through SharePoint.  These application involve a number of SharePoint lists, external databases, custom web parts, and other SharePoint elements to provide functionality.  About two weeks ago I received a message from one of our end users that a custom application was performing slowly.  Specifically performance was slow when users were performing actions that interacted with the primary SharePoint list storing data for that app.

The Problem

I took a copy of the production site into a dev environment to investigate the code that was executing.  After attaching the debugger and running through the code I quickly found pieces of code referencing SPListItem objects (like below) that were performing very poorly:

SPListItem myItem = SPContext.Current.Web.Lists["List Name"].Items.GetItemById(value);

// do updates on SPListItem retrieved

As it turns out the SPList I was referencing was fairly large at ~1000 items and weighing in over 150 MB.  You see the problem with my above code is that I retrieved the SPListItem by first (unnecessarily) going through the Items member of the list.  As I understand it, when doing so the executing code will attempt to resolve that entity and pull it from the database and into RAM (all 150 MB.)  This causes the equivalent of a 50 car pile up in terms of performance with a single update taking more than 15 seconds.

The Solution

The solution is actually quite simple and I wish I had realized this during development.  Instead of going through the Items member it is possible to call GetItemById(…) directly on the SPList as in the example below:

SPListItem myItem = SPContext.Current.Web.Lists["List Name"].GetItemById(value);

// do updates on SPListItem retrieved

After making this simple change performance skyrocketed and updates were back to less than a second.

Conclusion

When given the option between two solutions, usually the simplest is the best solution.  In my scenario I was adding extra complexity going through the API the long way around to get to the objects I needed and it ended up hurting performance greatly.  Luckily we were able to find and resolve the performance issue in a relatively short amount of time.  Like I said at the beginning of the post, learn from my mistakes and hope it helps you.

-Frog Out

Image linked from http://www.freespirit.com/files/IMAGE/COVER/LARGE/BeCarefulSafe.jpg

SPSiteDataQuery Returns Only One List Type At A Time

    The SPSiteDataQuery class in SharePoint 2007 is very powerful, but it has a few limitations.  One of these limitations that I ran into this morning (and caused hours of frustration) is that you can only return results from one list type at a time.  For example, if you are trying to query items from an out of the box custom list (list type = 100) and document library (list type = 101) you will only get items from the custom list (SPSiteDataQuery defaults to list type = 100.)  In my situation I was attempting to query multiple lists (created from custom list templates 10001 and 10002) each with their own content types.

Solution

    Since I am only able to return results from one list type at a time, I was forced to run my query twice with each time setting the ServerTemplate (translates to ListTemplateId if you are defining custom list templates) before executing the query.  Below is a snippet of the code to accomplish this.

SPSiteDataQuery spDataQuery = new SPSiteDataQuery();

spDataQuery.Lists = "<Lists ServerTemplate='10001' />";

// ... set rest of properties for spDataQuery

 

var results = SPContext.Current.Web.GetSiteData(spDataQuery).AsEnumerable();

 

// only change to SPSiteDataQuery is Lists property for ServerTemplate attribute

spDataQuery.Lists = "<Lists ServerTemplate='10002' />";

 

// re-execute query and concatenate results to existing entity

results = results.Concat(SPContext.Current.Web.GetSiteData(spDataQuery).AsEnumerable());

 

Conclusion

    Overall this isn’t an elegant solution, but it’s a workaround for a limitation with the SPSiteDataQuery.  I am now able to return data from multiple lists spread across various list templates.  I’d like to thank those who commented on this MSDN page that finally pointed out the limitation to me.  Also a thanks out to Mark Rackley for “name dropping” me in his latest article (which I humbly insist I don’t belong in such company)  as well as encouraging me to write up a quick post on this issue above despite my busy schedule.  Hopefully this post saves some of you from the frustrations I experienced this morning using the SPSiteDataQuery.  Until next time, Happy SharePoint’ing all.

 

      -Frog Out

 

Links

MSDN Article for SPSiteDataQuery

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsitedataquery.lists.aspx

Announcing Stir Trek: Iron Man Edition

    Today marks the official launch day of Stir Trek: Iron Man Edition.  This year’s conference will take place on Friday May 7th, 2010.  In case you are unfamiliar, Stir Trek is a regional conference hosted in Columbus, OH that focuses on covering topics from Microsoft’s annual Mix conference along with other web, mobile, and development related topics.  In addition to great session content from the conference, the day ends with a private screening of the new Iron Man 2 film.

    This is the second year for the Stir Trek conference and it is being expanded upon in every possible way.  More session tracks, more speakers, higher attendance capacity, and more excitement.  Here are a few things that you’ll get with your conference ticket [from the Stir Trek website]:

  • 6 hours of brand-new content, delivered by well-known regional and national speakers
  • Attendee packet
  • Lunch
  • Attendee T-shirt
  • A chance at winning prizes ranging from software licenses to an Xbox 360 and games.
  • Private screening of IronMan 2* at 4PM
  • Refreshments during the movie

    * An additional ticket to the movie can be purchased for $10.

     

        Last year’s Stir Trek conference sold out in less than 30 days, so don’t wait to reserve your spot.  Click here for registration.  Armor up your development skills today!

          -Frog Out

    Converting An Enter Key Press Into A Tab Key Press For Web Forms

    How many times have you been filling out an online form and halfway through filling in your responses you accidentally press the Enter key which then attempts to submit the form?  This can be a common problem when the online form is wired up to have a “submit” button be the default form button on a page.

    The most complete solution to this issue is having your submit process be able to handle all scenarios of submission (incomplete, invalid, etc).  If you are looking for a quick (partial) fix though, it is possible to trap the Enter key press and convert it to another key press (e.g. Tab key.)  A  few simple lines of JavaScript and adding a client-side event handler to your input controls can accomplish that.  I wish I could claim the credit for this, but I found this on many online resources (reference 1 and reference 2.)  Note: My example focuses on Internet Explorer; I have not tested against other browsers at this time.  Please read these references for more information on cross-browser compatibility.

    ConvertVans1

    My silly attempt at humor

    First, you’ll need to add a JavaScript function to trap the Enter key press (keyCode 13) and convert it to a Tab key press (keyCode 9).  Since my current work is on SharePoint development I place most of my JavaScript functions into an external file (previous blog post details) to be referenced by web part code.  Below are two examples, first on an HTML or ASPX page (includes tag) and second in an external file (without tag.)

    "JavaScript">

    function ModifyEnterKeyPressAsTab() {

        if (window.event && window.event.keyCode == 13) {

            window.event.keyCode = 9;

        }

    }

    
    

    JavaScript block on HTML/ASPX page
    function ModifyEnterKeyPressAsTab() {

        if (window.event && window.event.keyCode == 13) {

            window.event.keyCode = 9;

        }

    }

    JavaScript block in external file

        The next step is to call the above JavaScript function from an added client-side event handler to any input controls users will be filling out.  These input controls include textboxes, radio buttons, etc.  A client-side event handler (vs. server-side) are used so that  any key press will be intercepted before the server is able to respond (e.g. accept a premature form submit.)  Below is an example of adding the event handler to a Textbox.

    TextBox textbox1 = new TextBox();

    textbox1.Attributes.Add("onKeyDown", "ModifyEnterKeyPressAsTab();");

    In the above example, any time a user has focus on the Textbox and presses a key our JavaScript function will be called.  If the key press is Enter, the function will return a Tab key press which moves focus to the next control in TabIndex order.  Note: Since we are converting to a Tab key press, you’ll want to make sure the TabIndex of your controls is set appropriately so user’s are progressed in the desired order down/across the page.

    Conclusion

    Converting your Enter key press into another key press, such as Tab, is a rather crude workaround to a common problem of early form submission, but it’s a starting point to alleviating issues your end users may run into.  If you read the resources I linked to above you’ll notice there is additional information on how to make this solution more cross-browser friendly (specifically for FireFox vs. IE.)  If you have any comments on this topic or found this post helpful, feel free to leave feedback below.

    -Frog Out

    Fixing the SharePoint DateTimeControl MinDate Property (or How I Learned to Make the DateTimeControl Read-Only and Love SharePoint Controls)

    Excusing the long post title referencing Dr. Strangelove, I’d like to point out a small bug with the SharePoint DateTimeControl.  If you have ever implemented this control, you may find that you can set the MinDate property which is supposed to limit the range of dates allowed.  However, doing so only limits the calendar popup associated with this control, but the user can still enter a date below the MinDate into the textbox (see comments in reference.)

    I did a little searching on the interwebs and found the following post which described setting that textbox control read-only on the aspx page.  Below you will find the code to make it read-only in the code behind.

    using Microsoft.SharePoint.WebControls;

    
    

    DateTimeControl dtc = new DateTimeControl();

    dtc.DateOnly = true;

    dtcMinDate = DateTime.Today.Date;

    ((TextBox)dtc.Controls[0]).ReadOnly = true;

    In the last line, you will see that we are accessing a child control.  At a basic level, the SharePoint DateTimeControl is just a wrapper for 4 controls: a date textbox, an hour and a minute dropdown, and a required field validator.  Since the date textbox is the first control, we can cast it as a textbox and set the ReadOnly property and be all set.

    DateTimeControl1

    Before: able to edit textbox

    DateTimeControl2

    After: textbox is read only and calendar selection limited

    One other note about the DateTimeControl.  There is an issue with the SelectedDate property of the DateTimeControl not persisting through postback (reference 1 and reference 2).  Example scenario: if you set the SelectedDate on page load, change the SelectedDate through UI, then have a page postback (perhaps for a required field validation on another control) your change to the SelectedDate will be lost and the original value from during page load will reappear.  I have attempted all suggestions for enabling viewstate on parent container, removing Id, and clearing selection to no avail.  My next steps will be to convert this over to an AJAXControlToolkit Calendar Extender implementation and see if that works.  Expect a follow up post if that does fix the problem.

    As you can see, the SharePoint DateTimeControl is a nice option since you’ll have access to it out of the box with SharePoint, but there are a few bugs to be aware of when deciding whether to use it or not.  You might just be as well off building your own control to handle date selection.  If you’ve run into any other issue or have suggestions for fixes to the problems above please leave some feedback below.

    -Frog Out

    Links

    SharePoint DateTimeControl MSDN page

    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.datetimecontrol.aspx

    Make SharePoint DateTimeControl textbox read-only

    http://greggalipeau.wordpress.com/2008/06/27/sharepoint-datetimecontrol-validation/

    DateTimeControl SelectedDate issue

    http://www.eggheadcafe.com/software/aspnet/31645560/problem-with-sharepoint-d.aspx

    DateTimeControl ViewState issue

    http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/efe5602f-ed95-44c8-8722-077eacdb9844/