Please upgrade your web browser now. Internet Explorer 6 is no longer supported.
Zac Smith
SharePoint, WSS and MOSS development.

Configuring search on a public facing Web Content Management (WCM) site is quite a different task compared with your typical SharePoint intranet. Searching over internal content largely works out of the box; setting up a few content sources and basic scopes is usually enough to satisfy most users.

With a public website we want a simpler more ‘bing/google’ like search experience. The method of search is a basic search keyword phrase input and the power of the search resides in the indexing of content. We do not want to rely on a user’s ability to construct complicated search terms. Everybody can use it, and use it effectively.

What follows from here is a basic guide for setting up SharePoint search on an anonymously accessed SharePoint publishing site. This assumes a bit of experience configuring search, but if you don't take a look at this TechNet webcast on installing and configuring search in SharePoint Server 2007.

Creating Scopes

Creating scopes is the most important step in configuring public search. There are usually a number of resource files such as CSS, JavaScript, XSL and images as well as objects like user profiles that you wouldn’t want showing up in your search results. However we do want to be able to search over all of our document libraries, inlcuding aspx pages. So our first step is to create a scope that will return all pages and documents which we can create like this:

Public Search Scope Example

A search using this scope will return anything that is in the content source “Local Office SharePoint Server sites” AND (the content is a publishing page OR the content is a document). Note the brackets used in this statement.

As you can see the rule behaviour is being used to create logical conditions. The logic of the rules can be applied as follows:

  • Include = OR
  • Require = AND
  • Exclude = AND NOT

The ‘contentclass’ property specifies what type the indexed item is and will be automatically available for any content item in SharePoint. The two types that we are usually concerned with in a public site are:

  • STS_ListItem_850 (Publishing Pages)
  • STS_ListItem_DocumentLibrary (Documents)

Check out this post from Dan Attis for a complete list of contentclass values.

Tip

I would recommend against allowing list items in your search scopes. The basic reason for this is that to view a list item you need to browse to the display form (/Forms/DispForm.aspx). Problem is this should be locked down by the Form Lock down feature. Unfortunately it is common for lists to be used to store content for your public web site; for example when using WSS collaboration features such as blogs, wikis and discussion lists. At the end of the day the collaboration and publishing features in SharePoint don’t play very nicely together. When making design decisions for a SharePoint based solution and the question comes up - “Should we put this content in a simple list or create aspx pages?”, you should consider whether you want the content to be searchable or not.

Scope Examples

What if we wanted to create a scope that returned everything under a specific web? In this example I have added folder rule that will include all results in or beneath the 'about-us' site:

Public Scope for a web

 

What if we had a shared server environment that hosted multiple websites? In this example I have added a domain rule so that any results for my site 'http://trinkit' will be returned:

Public Scope for a Site

If you don’t know how to create scopes than have look at this help page from microsoft office online.

Tip

When indexing document libraries make sure that the documents are of a file type known to SharePoint, otherwise SharePoint will crawl the document as a list item and use the form display page rather than the actual document itself. Check out the filter pack from Microsoft if you want to add additional file types.

Creating a Simple, Deployable Layout

Armed with our public search scopes we already have enough information to return the right results. The next step is to create a simple search page to display search results.

When you create a search centre using the out-of-the-box search site template, you get a whole bunch of features that just aren’t that well suited to a public facing scenario (RSS Feeds, Alerts, Advanced Search). My recommendation is to take a light weight minimal approach - why use a whole search centre when a single results page will do it? Creating a single page layout that is part of an easily deployable SharePoint solution is often the cleanest way to go.

Web Parts

Web Part zones often cause issues when it comes to repeatable deployment and they add additional HTML bloat. If you are wanting the simplest HTML output possible then web part zones should be avoided.When it comes down to it we only really need a page layout with a few basic web parts – SearchBoxEx, CoreResultsWebPart and the SearchPagingWebPart.

Here is an example of using the CoreResultsWebPart in a search page layout without web part zone.

<Search:CoreResultsWebPart runat="server" 
    ID="SearchResults" 
    ShowActionLinks="True" 
    Scope="All Pages and Documents"  
    HighestResultPage="1000" 
    DuplicatesRemoved="True" 
    DisplayDiscoveredDefinition="True" 
    ShowSearchResults="True" 
    FrameType="None" 
    NoiseIgnored="True" 
    StemmingEnabled="True" 
    View="Relevance" 
    QueryNumber="Query1" 
    SentencesInSummary="3" 
    ResultsPerPage="10" 
    DateFormat="DateOnly" 
    DisplayAlertMeLink="False" 
    DisplayRSSLink="False" 
    RelevanceView="True" 
    WebPart="true">
    <XslLink>/XSL/CoreSearchResults.xsl</XslLink>        
    <SelectColumns>
        <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Columns>
                <Column Name="WorkId"/>
                <Column Name="Rank"/>
                <Column Name="Title"/>
                <Column Name="HitHighlightedProperties"/>
                <Column Name="Size"/>
                <Column Name="Path"/>
                <Column Name="Description"/>
                <Column Name="PictureThumbnailURL"/>
                <Column Name="SiteName"/>
                <Column Name="CollapsingStatus"/>
                <Column Name="HitHighlightedSummary"/>                
                <Column Name="ContentClass"/>
                <Column Name="IsDocument"/>
                <Column Name="Write"/>
                <Column Name="Author"/>
                <Column Name="ContentType"/>
            </Columns>
        </root>
    </SelectColumns>        
</Search:CoreResultsWebPart>

The other web parts can be added to the page layout in the same way.

Tip

Make sure search.js is inlcuded in a custom search page layout as it is needed for logging search statistics: 

<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
    <SharePoint:ScriptLink ID="ScriptLink1" name="search.js" runat="server"/>
</asp:Content>

  

Additional Branding Considerations

The majority of the branding is quite easy due to the core search results web part using an XSL transformation to style the results. Unfortunately the other web parts will require tedious battling with overriding of SharePoint’s CSS properties. Not ideal but you can still get it looking pretty decent if you know what you are doing.

For full control of the HTML structure and styling you would need to create a bespoke solution that used the search SQL Syntax API that comes with MOSS. This is also the only solution if you require some advanced sorting or filtering functionality. This isn't overly difficult, but it's a tough one to explain to the business owner that is forking out for SharePoint.

So what about advanced search? I think we’ll leave that one for another day.

I hope this post gives you a few ideas and some "best practices" on you can go about creating a decent search solution for you public SharePoint website.

Good luck!

Categories: Development, MOSS, Search, SharePoint, WCM

The other day I was messing around with the MOSS search web service (search.asmx) when I ran into a bit of a show stopper. Every time I tried to execute a method on the web service on a particular site I got the following error:

Attempted to perform an unauthorized operation.

Now it turns out that if anonymous access is enabled, the search service will return this error whether you are accessing it anonymously or not. In fact even if you haven’t enabled anonymous access at the site level it will still not work. In this case it is still enabled at the web application/zone level and hence in IIS. I believe this is only an issue with the search web service, but I can’t confirm that.

So I have come up with three different solutions to address the issue, and the right solution will depend on your scenario:

  1. Disable anonymous access on the search.asmx file in IIS.  Doing this means that anonymous access is enabled for everything except the one web service that doesn’t like it. The bad thing about this approach is that it requires a manual edit in IIS putting SharePoint and IIS out of sync. This may mean the setting gets overwritten later, or it may have strange affects if you later disable anonymous access for the whole site.
  2. Use the URL of another non-anonymous enabled SharePoint site (could even be central admin). This is a good quick fix if you are trying to put together a prototype or something, but not the best in a production environment. Reason being that the user account used for the search service access will need to authenticate on the other site.
  3. Extend the web application to provide a non-anonymous zoned IIS site – you may already have one. This is my recommended approach, but like many best practices it is the most complicated/time consuming/puts biggest load on server. See this article on TechNet if you are unsure how to go about that.

So why was I playing with the search web service anyway? Why not just use the object model? Or better yet why not use the OOTB search webparts? Basically I wanted more flexibility, I wanted to use the search components of MOSS as a remote service that doesn’t require SharePoint context. For example utilising search from a separate non-SharePoint web application. An even more interesting use might be to provide anonymously accessible people search.

There are also some great search web service controls available from the awesome SharePoint search community tool kit.

Categories: MOSS, SharePoint, Search

There are a lot of cool things you can do when working with profile functionality in SharePoint - e.g. people search, my sites, audiences, people based workflow, profile management..

 

But when it comes to developing and testing it can be hard to tell how well things are working unless you have a bunch of test users with meaninful profile data.

 

If you've ever used one of Microsofts virtual machines that come with the litware test domain, you'll be familiar with Don Funk, Brian Cox and the rest of the gang. Those are all active directory accounts with profile data including direct reports which is great for testing org charts.

 

So how can we get those accounts into our own AD domain?

Easy - Use the LDFIDE tool that comes with windows server. Exporting the accounts into a file and importing that file into a different domain does present a number of problems: the domain name is different, many exported fields are read only, passwords cannot be imported. I've gone ahead and solved those problems for you, so if you want to import those users into your own domain just follow these steps:

  • Download the Sample Users text file. Replace the test domain values with your own. I use DC=mossdev,DC=local. I also have all email addresses going to mossdev.com which is a local mail service. I have a catch all email account setup so that all emails to my users feed into the one outlook inbox. I have also specified an OU called Profile Accounts to keep them seperate from all of the default accounts.
  • From the command prompt run
      ldifde -i -k -f c:\sampleadusers.txt
    To import all the users, you will need to keep running the command until all users have been processed. This is because of the dependicenies between managers/direct reports.
  • Download the Update Passwords text file and replace unicodePwd with your own base64 encoded password. The password in that text file is "P@ssw0rd" which I often use for test accounts. If you are encoding your own password its important to use a unicode encoding of a string. The string value would look something like "\P@ssw0rd\". You'll only need the passwords if you actually want to log in with the accounts.
  • From the command prompt run
     ldifde -i -h -f c:\updatepasswords.txt
    to update all the passwords.

Now you should have a domain of 78 users full of profile info that you can play with.

Now I can log in as Don, create a mysite and view his profile properties along with org chart:

 
dons profile
 
 
Categories: MOSS, SharePoint, WSS, Search, Development