April 2009 - Posts

If you’re like me, you like to have as few manual steps in your deployment documentation as possible.  It’s easy to use the UI of your SSP to add a file extension to the list.  However, I would rather have code put those settings in there for me.  That is just one less thing the next person has to worry about when deploying to a new server.  The code is quite simple for this. 

The first thing you want to do is add a reference to the search administration assembly.

using Microsoft.Office.Server.Search.Administration;

The first thing you need to do is get access to the Content object which lets you configure various things in Enterprise Search.  You do this by passing an instance of SearchContext.Current which represents the search service on the current SSP.

Content serverContent = new Content(SearchContext.Current);

Once you have a reference to the Content object, you can use the ExtensionList collection to create the new file type.  The Create method takes a string with the file type.  In this case, a period is not included in the file extension.  That means you would pass png instead of .png

serverContent.ExtensionList.Create("png");

That is really all that is required.  Just two lines of code.  The Content object will allow you to make many other changes as well to your search settings, such as content sources, property mappings, crawl rules, etc.  You can write code to configure these too, but I still use the SharePoint Shared Services Provider Property Creation tool quite a bit.

Follow me on twitter.

Today, I had the opportunity to give a short introduction on how to do some basic queries on XML documents with LINQ to XML.  In the talk, I talked about how to create anonymous types from your XML document so that you can work with strong types.  I also showed some uses some of the classes, methods, and properties, they would use most when working with LINQ to XML. 

I also discussed how LINQ to XML can be used to make working with repeating tables in InfoPath easier.  Consider the following XML of an InfoPath form.  We have a repeating table called RepeatingTable and in the table there is element called Item.

<?xml version="1.0" encoding="utf-8"?>

<my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

             xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2008-12-30T15:48:37"

             xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-US">

  <my:RepeatingTable>

    <my:Item>

      <my:Name>Polo Shirt</my:Name>

      <my:Color>26134</my:Color>

      <my:Price>19.99</my:Price>

    </my:Item>

    <my:Item>

      <my:Name>Jeans</my:Name>

      <my:Color>01823</my:Color>

      <my:Price>29.99</my:Price>

    </my:Item>

  </my:RepeatingTable>

  <my:Id>83123</my:Id>

</my:myFields>

If you needed to work with this repeating table when the InfoPath form was loaded again, you could use code like the following.  You could also apply a similar technique to work with this data inside a workflow.

// use the MainDataSource to read the XML of the InfoPath Form

XDocument infoPathDocument = XDocument.Load(new System.IO.StringReader(MainDataSource.CreateNavigator().OuterXml));

// required to access my: namespace

XNamespace myNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2008-12-30T15:48:37";

// use descendants node to find any element with the name Item in the tree

var items = from item in infoPathDocument.Descendants(myNamespace + "Item")

            select new

            {

                Name = item.Element(myNamespace + "Name").Value,

                Color = item.Element(myNamespace + "Color").Value,

                Price = item.Element(myNamespace + "Price").Value

            };

foreach (var item in items)

{

    // do something

}

In the code above, I use the CreateNavigator method of the MainDataSource as usual when working with an InfoPath form and I use a StringReader to load it into an XDocument.  Since InfoPath form’s always use the my namespace it is necessary to declare it using the XNamespace object and use it before referring to any element or attribute in the document.  In the example above, I create a new anonymous type with the Name, Color, and Price and then I can use a foreach loop to iterate through the items.

I have attached the code for the example above as well as the other examples I mentioned in the talk to this post.  Please, let me know if you have any questions.

Follow me on twitter.

Last night, I had the opportunity to speak at the Tulsa .NET Users Group.  I spoke about automating web testing using Visual Studio Team Test.  This is usually the post where I post my slides and code samples, but this talk did not have any slides, so I thought I would give a quick recap.  In the talk, I showed how to record a web test using Visual Studio Team Test.  I showed how to set up a basic validation rule and demonstrated passing and failing tests.  Lastly, we ran through a coded test and showed how you can use existing tests to perform load testing.  I had a great time giving the talk.  Thanks for attending.

Follow me on twitter.

Today, I am going to talk about how to work with the My Links functionality in MOSS using the API.  The first thing to know is that the API calls it a QuickLink.  Knowing this makes it that much easier on finding information you need in the SDK to work with them.  I figured this list worked like a regular SharePoint list, but in fact it is quite a bit different (which is why I am posting today).  QuickLinks are tied to the user’s profile in MOSS, so you will need to make a reference to Microsoft.Office.Server.dll, if you haven’t already.  You’ll then want the following references in your class.

using Microsoft.Office.Server;

using Microsoft.Office.Server.UserProfiles;

The first step is to get a reference to the UserProfileManager.  You’ll need to pass in a reference to the current SSP by using ServerContext.Current.

UserProfileManager userProfileManager = new UserProfileManager(ServerContext.Current);

After that you get the current user’s profile.  Passing true, will create the user’s profile if it doesn’t exist.

UserProfile currentUser = userProfileManager.GetUserProfile(true);

The QuickLinkManager class provides what we need to add, remove, or iterate through the links the user currently has.

QuickLinkManager quickLinkManager = currentUser.QuickLinks;

quickLinkManager.Create("My Quick Link", "http://www.dotnetmafia.com", QuickLinkGroupType.General, null, Privacy.Private);

Once we have a reference to the manager, a call to the Create method is all we need.  It takes a few parameters.  The first parameter is the title followed by the URL.  The third and fourth parameters, can be used to specify a built-in group (using the QuickLinkGroupType.General enum) or by specifying a string in the next parameter to create a new one.  Finally, the last parameter, specifies the privacy settings of the link.  For the purpose of the My Links menu, you would usually choose Privacy.Private.  However, you can specify other settings as well for sharing the users links on his or her My Sites page.

You can also iterate through the user’s QuickLinks pretty easily using the GetItems() method.  For example:

foreach (QuickLink quickLink in quickLinkManager.GetItems())

{

    Console.WriteLine(quickLink.Url);

}

Follow me on twitter.

with 6 comment(s)
Filed under: ,

Next week on April 27th, I have the privilege of speaking about Automated Web Testing using Visual Studio Team Test at the Tulsa .NET Users Group.  This is an updated version of the talk I originally gave about four years ago at DTG.  At the time, I gave the talk using Visual Studio 2005, but for this talk we’ll be using Visual Studio 2008 and using the added features it brings us.  This is my first non-SharePoint talk in a while, so I am excited to be able to talk about a different topic with some new people.  I am happy to say there won’t be any slides on this talk, it will be nothing but using Visual Studio.  Tulsa DNUG is located at TCC Northeast Campus (3727 E. Apache).  It starts at 6pm.  Dennis Bottjer has more information on tonight's event.  Look forward to seeing you there.

Follow me on twitter.

Recently, I was troubleshooting and Enterprise Search / BDC issue and I encountered the following error when trying to view the entity page of a given LOB system.

Entity id is invalid

As usual, this error was completely and totally useless.  I really needed to be able to view the details of my entity to ensure proper configuration and security settings, so I decided to pursue an answer.  After looking at the 12 hive logs as well as the event log, I found the following error.

Runtime Error in method ViewBDCEntity.OnLoad of type System.UriFormatException.The exception was System.UriFormatException: Invalid URI: The hostname could not be parsed.

In this particular application definition, I am appending a relative URL onto a server name.  So in this case, my action url looks like http://server{0} where my Action Paramter would contain something like /Sites/SomeSubSite.  SharePoint does not like this one bit.  Although, the search crawler has no issue with it and you will be able to link to sites fine, this causes the BDC entity page on your SSP to completely die.

How did I resolve it?  I tried just adding a slash after the server name (i.e.: http://server/{0}).  This works, but you do end up with two slashes in your URL.  I’m not sure of a better way to fix it for now, so it will have to do for now.

Follow me on twitter.

I get asked a lot about what I put into a MOSS virtual machine, so the last time I built one, I actually took the time to document each thing I did and the order in which I did it.  Getting a MOSS virtual machine just right can take some work.  This is actually the third one I have built in this environment and I am finally pretty happy with it.  Ultimately, the image will contain Windows Server 2008, SQL Server 2008, Active Directory, MOSS 2007 (Kerberos enabled with SP1 and Infrastructure Update), and Office 2007.

Virtualization

With my latest image, I went with Microsoft Virtual PC.  I don’t have VMWare workstation, so this is what I am stuck with.  It may not have the features that VMWare does but ultimately it still gets the job done.  This unfortunately limits me to 32 bit, but at this time that is not a deal breaker for me.  As for memory allocation, 1 GB is probably the absolute minimum you can get away with.  2 GB or more is better.

Windows Server 2008

For some reason, I keep seeing people build virtual machines with Windows Server 2003.  That operating system is six years old.  It’s time to upgrade.  Windows Server 2008 comes with IIS7 and works great with MOSS 2007.  The edition I usually go with is Data Center edition.  You can use Standard or Enterprise as well, but avoid Web since you are going to want to be able to promote the server to be a domain controller.  There aren’t many options in the install of Windows Server, so just install it as is and it can be configured once it is done.

Once Windows Server is installed, there are a number of things you should do before even considering installing software.  The first thing I always do is set the time zone.  You don’t want your server thinking it’s on the west coast when it is really on the east.  The next thing you want to do is set the computer name.  You can do this right from the Server Manager screen that pops up every time you login.  Set your server name to something meaningful and reboot it.  I usually go with a name of something like moss-server.

Virtual Machine Addons

Whatever, virtualization platform you choose, be sure and install the addons, so that things like the mouse work right and the time gets synchornized with the host computer

Windows Server 2008 Roles

Once you reboot, you will need to use the Server Manager to configure a few things about your server.  First, you are going to want to install the DNS Server role.  This is necessary for Active Directory.  When you promote your domain controller, it might actually install this service for you now, but this is the way I have done it since Windows 2000 Server.  It will complain that your IP address is being assigned via DHCP.  Just ignore the warning and continue anyway.

The next role, you need to install is the Web Server role since SharePoint obviously requires IIS.  When you select this role, a number of role service options get checked automatically but there are a few extras that you will want.  Specifically, make sure that ASP.NET, Basic Authentication, Windows Authentication, and Digest Authentication are all checked.

Active Directory

I prefer to install MOSS on a server that has Active Directory.  If you are in an environment, where you want to attach to an existing active directory you can skip this step (as well the DNS role from earlier).  However as a consultant, many times, I want my MOSS server to be independent of any organization’s directory for my own testing purposes.  For those of you who are new to creating domain controllers, dcpromo.exe, is what you run to start that process.  It should install the necessary Active Directory Directory Services role that you will need.  It will again complain about not having a static IP address.  Ignore it and continue.  You should be able to use the default options.  I think I usually use the Windows Server 2003 compatibility level, but it shouldn’t really matter for SharePoint development.  As for a name of the domain, I usually go with something like MOSSTEST.  You can set it to whatever you want, but for the purposes of this post, MOSSTEST (NT4 name) and mosstest.local (Active Directory name) will be used.

Network Accounts

Now, that Active Directory is installed, you will want to create several accounts that will be used for the services and installation of MOSS.  I recommend using the same password for each (since this is for a development virtual machine).  I also recommend storing your password in a text file with the rest of your virtual hard disk files on the host file system since I have forgotten the password to a VM more than once.  Here is a list of the accounts that I typically use.

Network Account

Description

MOSS_Setup

Administrator account used to install MOSS.
SQL_Service Service account for SQL Server
MOSS_AP_CentralAdmin Application Pool account for Central Administration
MOSS_AP_SSP Application Pool account for the Shared Services Provider
MOSS_AP_Portal Application Pool account for the Port 80 site
MOSS_SSP Shared Services Provider account
MOSS_WSS_Search SharePoint Search Service
MOSS_Search MOSS Search Service
MOSS_Crawl Enterprise Search Default Content Access Account

All accounts except for MOSS_Setup are just regular user accounts.  The setup account you will use for the installation of MOSS and requires administrator permissions.  You can of course name these accounts anything you want.  This is just a guideline for some suggested names.

SQL Server 2008

The next step is to install SQL Server 2008.   Use the SQL_Service account when prompted for any service accounts.  I typically try to keep the installation small and only install SQL Server and the tools.  If you think you might use Analysis Services or Reporting Services, feel free to install those as well, but chances are you won’t need them.  Use default settings for everything else in the install.  Also note, that this will install .NET Framework 3.5 for you.

Slipstream Service Pack 1 and the Infrastructure Update

Installing MOSS 2007 on Windows Server 2008 requires you to slipstream SP1 into the install media.  This requires you to extact the installation contents of the CD (or ISO image) into a folder.  You then extract the contents of the SP1 installer into the Updates subfolder.  I also recommend you do the same procedure for the Infrastructure Update.  Emmanuel Bergerat has an excellent post on how to do this.

Install MOSS 2007

Once you have completed the slipstream process, it is time to begin the installation of MOSS.  I typically don’t use the administrator account to do this but instead use another account with administrator privileges.  In this case I am using the MOSS_Setup account.  You will want to do an Advanced Install with a Complete installation.

When the install is complete, the Configuration Wizard will start and you will have a few more options to set.  Choose the Create a New Farm setting and then use the settings below as guidelines.  You can use whatever database name or port number you want, but here is what I have used in the past.

Setting Value
Database Server .
Database Name SharePoint_Config
Service Account MOSSTEST\MOSS_AP_CentralAdmin
SharePoint Central Admin Port Number 8100
Security Settings Negotiate (Kerberos)
Configuring Kerberos on the Central Administration Site

At this point, if you try to visit the Central Administration site and login, you aren’t going to get very far.  This is because Kerberos has been enabled but not configured on the domain.  Martin Kearn has an excellent post on the setspn.exe commands you need to run to enable kerberos.  At this time, you will want to follow all of the  steps in that post that apply to Central Administration.  After you can access Central Administration, you will follow the steps in the post to apply kerberos to the SSP and the web application you create on port 80.  If you don’t feel the need to use kerberos on your Virtual Machine, you can always just use NTLM and skip these steps.

Windows SharePoint Services Search

Once Central Administration is up and running, go to Services on Server, and click start on Windows SharePoint Services Search.  The default settings should be used unless otherwise noted.

Setting Value
Service Account MOSSTEST\MOSS_WSS_Search
Content Access Account MOSSTEST\MOSS_Crawl

Search Database Server

.
Search Database Name WSS_Search_moss-server
Search Database Authentication Windows
Office SharePoint Server Search

You will then need to start the Office SharePoint Server Search service from the Services on Server page.  When you finish this, go ahead and start the other services using the default settings.

Setting Value

Use this server for indexing content

Checked
Use this server for serving search queries Checked
Contact E-mail <any e-mail address>
Service Account MOSSTEST\MOSS_Search

Indexer Performance

Partly Reduced
Search Database Name WSS_Search_moss-server
Creating the Web Application for the Shared Services Provider

When dealing with a new install, I find it best to go ahead and configure the Web Applications for both the SSP and the main web site (usually on port 80).  Here are the settings I usually use.

Setting Value
Port 8101
Path C:\Inetpub\wwwroot\wss\VirtualDirectories\8101
Authentication Kerberos
Load Balanced URL http://moss-test:8101
Application Pool SharePoint SSP
Application Pool Account MOSSTEST\MOSS_AP_SSP
Restart IIS Restart IIS Manually
Database Server .
Database Name WSS_Content_SSP
Database Authentication Windows
Creating the Web Application for the Portal Site (Port 80)

You now need to create a web application for the main SharePoint site (usually hosted on port 80).  Be sure and configure Kerberos if you enabled it on this site as well as the SSP.

Setting Value
Port 80
Path C:\Inetpub\wwwroot\wss\VirtualDirectories\80
Authentication Kerberos
Load Balanced URL http://moss-test:80
Application Pool SharePoint - 80
Application Pool Account MOSSTEST\MOSS_AP_Portal
Restart IIS Restart IIS Manually
Database Server .
Database Name WSS_Content_80
Database Authentication Windows
Shared Services Provider

The next step will be to configure a Shared Services Provider (SSP).  Since you have already created the needed web applications, it simplifies this step quite a bit.

Setting Value
SSP Name SharedServices1
Web Application SharePoint – SSP (Created on port 8101 above)
My Site Web Application SharePoint - 80
My Site Relative URL /MySites (Some may prefer to put this on its own web application)

SSP Service Account

MOSSTEST\MOSS_SSP
SSP Database Server .
SSP Database SharedServices1_DB
SSP Database Authentication Windows
Search Database Server .
Search Database Name SharedServices1_Search
Search Database Authentication Windows
Index Server MOSS-SERVER
Index Path C:\Program Files\Microsoft Office Servers\12.0\Data\Office\Applications

SSL for Web Services

No
Site Collection

At this point you’ll need to create a Site Collection on your port 80 site.  Use any site template you prefer.  You may want to also set up some other accounts as site collection administrators besides just MOSS_Setup.

Internet Explorer

At this point, your SharePoint Server should be operational.  However, there are a few more settings to make as well as some additional applications you might want to install for development.  You will want to configure Internet Explorer, so that you don’t have to type your credentials every time you open a SharePoint site.  To do this, go to Tools –> Internet Options –> Security.  From here, scroll to the bottom and choose Automatic login with current user name and password.  More information in this post.

Visual Studio 2008

At this point, you are ready to start installing developer tools.  Don’t even think of using Visual Studio 2005.  Install Visual Studio 2008, using whichever options you like and then be sure and install Service Pack 1.  If you are connecting to a TFS server, be sure and install TFS explorer as well.  Once everything is installed, you can install some of the SharePoint tools if you so choose.  Popular ones are VSeWSS 1.3, WSPBuilder, and Stsdev.

Microsoft Office 2007

If you plan on doing any ECM development, then I recommend installing Office.  Otherwise, you may not need to worry about it.  Do a custom install and just choose the pieces you think you might need (i.e.: Word, Excel, PowerPoint, Publisher, etc.). 

SharePoint Designer 2007

If you read any blog at all, you know that SharePoint Designer 2007 is now free, so go ahead and install it.  Occasionally, it has some use.

SharePoint Features

I tend to activate a few builtin MOSS features such as publishing.   Here are the Site Collection Features I usually activate.

Feature Notes
Office SharePoint Server Enterprise Site Collection features  
Office SharePoint Server Pubishing Infastructure Activate by using stsadm -o activatefeature -name publishingresources -url <server>
Office SharePoint Server Search Server Web Parts  
Office SharePoint Server Standard Site Collection Features  

Here are some site features you may activate at your root site.

Feature Notes
Office SharePoint Server Enterprise Site Features  
Office SharePoint Server Publishing  
Office SharePoint Server Standard Site Features  

When you complete all of these steps, you should have a fully functional development environment for developing SharePoint applications.  I am sure there are things I have missed, so I’ll update this post as I find them.  This whole process will probably take 4 – 8 hours depending on your hardware and your familiarity with SharePoint and Windows Server.  I would love to just post my working virtual machine, but obviously due to licensing I can’t do that. :)  I hope this gets new developers in getting an environment started.  Post a comment if you have any questions.

Follow me on twitter.

I’ve have been using SharePoint’s DelegateControl a lot again lately.  If you are not familiar with it, it allows you to drop a placeholder on a page and then later specify what control goes in it by activating a feature.  You can effectively use it as an alternative to the SmartPart for putting user control’s on pages when you are deploying custom pages (i.e.: in a site definition or via publishing).  However, one thing I have discovered is that if something goes wrong with the delegate control, there is absolutely zero feedback on the page to let you know that your control could not be loaded.  It simply just displays the page without your control. 

This is pretty annoying, but it is pretty easy to figure out what the issue is.  As I have said many times in the past, the LOGS folder in the 12 hive is your friend.  Most issues you have in SharePoint can be resolved by taking a look at this folder.  For my latest issue, I opened up the latest log file, to find the following entries.

04/01/2009 14:56:21.98  w3wp.exe (0x6DA4)                        0x6980 Windows SharePoint Services    General                        8e1n High     Failed to create a user control from virtual path '/_ControlTemplates/MyControls/MyControl.ascx': Type 'System.Web.UI.WebControls.ListView' does not have a public property named 'ItemSeperatorTemplate'. 

As you can see in my case, I was stupid and misspelled ItemSeparatorTemplate on my ListView control.  This caused my control to throw a runtime exception.  In a way I guess you can argue that this is nice, because the DelegateControl caught the exception and the entire page didn’t die with a yellow screen.  However, it would be nice if the error could be reported without having to dig through the LOGS folder.  Just remember any unhandled exception your user control might throw will cause the delegate control to display nothing.  If you want more information on the DelegateControl, MSDN has some decent information on it.

Follow me on twitter.

with no comments
Filed under: ,