Tuesday, February 2, 2010

Using Microsoft.SharePoint.dll to find out the ID of a list

When moving a site between web applications using SharePoint Designer backup (Site > Administration > Backup Web Site menu), several web parts wich had been converted to XSLT were displaying a "strange" message:

The server returned a non-specific error when trying to get data from the data source. Check the format and content of your query and try again. If the problem persists, contact the server administrator.

When an web part is converted to XSLT, SharePoint Designer places on the page a control of type WebPartPages:DataFormWebPart to display the data. This control uses the list ID to specify wich list is the data source (each list in a SharePoint site is given a GUID as its identifier, wich is stored in the list's ID property). Well, when the site was recreated at the destination, so were its lists, and that generated new ID's to them. And the web parts could not find their lists anymore, so they stopped working.

Being a restless geek, I decided to test the classes on Microsoft.SharePoint.dll by coding a little console app that listed the ID's from a SharePoint site lists. The code is bellow, and can be used as an intro to classes in namespace Microsoft.SharePoint. If you want just the app, just download the following file and run it from a command prompt on your SharePoint machine: SPListId.zip.

Imports Microsoft.SharePoint

Module Module1

Sub Main()
Try
Console.WriteLine()
If My.Application.CommandLineArgs.Count = 0 Then
Console.WriteLine("SPListId - Lists IDs from lists in a SharePoint site")
Console.WriteLine("Copyright (c) 2010 SrNimbus. No rights reserved ;)")
Console.WriteLine("Usage: SPListId site_url")
Return
End If
' The System.Uri class helps manipulating network addresses
Dim urlSite As Uri = New Uri(My.Application.CommandLineArgs(0))
' The Microsoft.SharePoint.SPSite class represents a site collection on SharePoint
Dim siteCollection As New SPSite(urlSite.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped))
' The Microsoft.SharePoint.SPWeb class represents a site on a site collection
Dim site As SPWeb = siteCollection.OpenWeb(urlSite.AbsolutePath)
Console.WriteLine("Lists on {0}:", urlSite.OriginalString)
Console.WriteLine("------------------------------------")
' The SPList class represents a SharePoint list
For Each lista As SPList In site.Lists
Console.WriteLine("{0}: {{{1}}}", lista.Title, lista.ID.ToString().ToUpper())
Next
Console.WriteLine("------------------------------------")
Catch erro As Exception
Console.WriteLine("Ooops:")
Console.WriteLine("{0} - {1}", erro.Source, erro.Message)
Finally
Console.WriteLine()
End Try
End Sub

End Module

Remember to add a reference to Microsoft.SharePoint.dll in order to compile the project. It is located on the SharePoint server, at %ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI.

Monday, January 25, 2010

SharePoint 2007 Content Deploy Quick Start Guide

And there was I working my 455 off preparing for teach Microsoft´s 50149 SharePoint Operations training when...
A word of advise: stay away from this training. The author tries to show EVERYTHING about SharePoint operations but there's no details on *any* of the topics shown. The result is frustrated and/or distracted students, and that's a saddening thing to me as an instructor - not to mention to the students...
Well, there I was studying the module on Content Deployment when I stumbled upon this guide from Stefan Gossner (great SharePoint blog!). It gives a quick and straightforward view on the main points about Content Deplyment on SharePoint 2007. Nice reading if you are new to the subject. Till now, the guide covers the following:

Part 1 - The Basics
Part 2 - The Basics continued
Part 3 - Configuration
Part 4 - Communication
Part 5 - Quick Deployment
Part 6 - Logging
Part 7 - Change Token Basics
Part 8 - Job and Change Token

Part 1 has an link index to the other parts. Enjoy!

Tuesday, December 29, 2009

Windows Virtual PC: Where is it?

Windows Virtual PC is Microsoft Virtual PC next version. It runs on Windows 7, but it is NOT part of it - you have to download it. The download page is http://www.microsoft.com/windows/virtual-pc/download.aspx, although the page title is "Download Windows XP Mode". You have to fill in the two dropdowns, and the page shows you two links. If you don't want Windows XP Mode, just click the second link, download and install the update to Windows 7 - it's Windows Virtual PC that's being installed.



Before you download it, you have to check if your's computer processor supports hardware virtualization technology (check out the links on Intel and AMD on the article). Most of the newer processors (post 2006-) ship with it. Some don't (for example, the T6670 on my Dell Vostro 1310 does not :-P). You can run the Hardware-Assisted Virtualization Detection Tool from Microsft to confirm that your processor supports VT (virtualization technology). If it doesn't, download Virtual PC 2007, the previous Windows Virtual PC version. It has less features, but it's disks are compatible with Windows VPC.

Thursday, December 24, 2009

Disk space used by an Windows 2003 Clean Install

Old one, but just for the record: a fresh Windows 2003 Standard + IIS + SP2 takes 5.74 Gb on the disk. In case you need to build a VM with that.

Friday, December 18, 2009

SELECT * FROM Table JOIN... ListBox???

A Linq way to retrive rows from one table based on rows from a related table whose lines are loaded into a listbox.

The ASP.NET test WebForm:



I want all products related to the selected categories (ListBox.SelectionMode = Multiple). The project is an ASP.NET Web App on VS 2010 Beta 2, and it contains an Entity Data Model on the Northwind sample database.

The LinkButton code:

    Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles LinkButton1.Click
Dim data As New NorthwindEntities
Dim selectedCategoriesProducts As New List(Of Products)
selectedCategoriesProducts = _
(From line As Products In data.Products
Join item As Integer In (From x In ListBox1.Items Where x.Selected = True Select x.value)
On line.CategoryID Equals item
Select line).ToList()
GridView1.DataSource = selectedCategoriesProducts
GridView1.DataBind()
End Sub
The Linq (to Entity) query joins the Products table (data.Products) to a integer list (Join item As Integer). The integer list is generated by a Linq (to Objects) query that selects the values (Select x.value) from the listbox options (ListBox1.Items) that are checked (Where x.Selected = True). The returned Products object list is then shown on the GridView.

In other words, we joined the Products table on Nortwind database with the ListBox selected items from an webform. Well, talk about data source abstraction... :-)

"Linq Is Fun!!!"
Buda On Using Linq To Query Data

Monday, November 9, 2009

Visual Studio: how to target different .NET Framework versions

We are creating a WPF application on Visual Studio 2010 (beta 1), but Blend 3 doesn’t load .NET Framework 4.0 assemblies. So on the designer’s machine we had to compile the solution targeting .NET Framework version 3.5.

(quick thought: our development team is made up of one designer, one product manager, and one project manager. So, WHO IS CODING???)

We found an article on MSBuild – Microsoft’s build engine – about the /toolsversion option, that targets specific .NET Framework versions. We built a .bat file that recompiles all projects in the solution. Following is some of it:

msbuild StorageClient\StorageClient.csproj /toolsversion:3.5 /verbosity:quiet
if ERRORLEVEL 1 goto erro

MSBuild recognizes Visual Studio project files, and activates the corresponding compiler. The /toolsversion option selects the target .NET Framework version (allowed values are 2.0, 3.0, 3.5 and 4.0), and overrides the selected version on the project file. The following “if” checks if MSBuild returned 1, which signals an error, so you can stop the build job (using good(?) old goto).

A lot less painful than I thought. The same batch will be used to generate a 3.5 version of the solution when building the tables on Azure Development Storage, because DevTableGen – the utility that builds the tables – also does not support 4.0 .NET Framework assemblies.

MSBuild location is not included on the standard command prompt path, so use Visual Studio 2010 command prompt (VS 2010 program group > Visual Studio 2010 Tools).

Monday, October 26, 2009

INSERT's inside transactions

Are you a geek? Then read on. :-)

Reading Inside SQL Server 2005: Query Tunning and Optimization, I stumbled upon this beaultiful code sample. The guy (yes, a guy - it seems Ms. Delaney is subcontracting for some chapters...) creates a big sample table with 250,000 rows on it.


And there's not a single shred of comment about the code. He's doing 250,000 INSERT's on a table. In order to optimize it, he opens a transaction right before the loop starts, and on every 1,000 INSERT's he does a COMMIT then opens another transaction. This prevents SQL Server from opening a transaction on each INSERT. (Yes, Luke. When a data modification command to SQL Server you send, a transaction it automatically opens if the command is not already inside one. This allows you, for example, to change your mind and issue a ROLLBACK inside a trigger - even without a preceding BEGIN TRAN).

By using the explicit transactions around the INSERT's, the code runs them on 250 transactions, instead of 250 thousand ones. As I've said before, beaultiful. Simply beaultiful.

And in case you didn't notice: yes, I'm a geek. :-)