SharePoint

Syrinx SharePoint Team Blog
Need help on your project? info@syrinx.com, or toll free (888) 579-7469, press 1

News



Need help with your SharePoint project?

Syrinx works with clients throughout New England and across the United States to architect, design, develop, and deploy SharePoint implementations. Working on fully outsourced projects, as part of your team, helping to train your team, or rescuing projects in trouble, we are comfortable doing it all. Projects from a couple weeks to several months in duration, reference clients available. Contact us today - info@syrinx.com, or toll free (888) 579-7469 and press 1 to speak to someone now!

April 2008 - Posts

Custom Alert Handlers: Part 1 of 2

Have you ever wanted to modify the contents of an Alert Email from SharePoint 2007. We had a requirement recently, from a client, to modify the contents of alert emails in a very specific way. They wanted to change not the layout but the contents, and they wanted the contents to be different based on the content type.

I started by looking at what I could achieve using CAML and updating the alerttemplate.xml file. I quickly came to the decision that this approach was not viable and so switched to building an Alert Event Handler. Alert Handlers are called just before an alert email is to be sent. The handler has the ability to modify the email contents as well as decide not to send it.

There are a few steps to creating an Alert Handler, these break down into three broad steps:

  1. Create and register the handler
  2. Create an alert template that requires the handler
  3. Attach the template and handler to a list or lists

It is best if the alert template can be attached to a new list, prior to any users creating alerts. The reason for this is that the alert points to the alert template that the list was using at the time the alert was created. So if you update the template a list is using, you will need to update all the existing alerts . For my client they had a large number of existing alerts, so I needed to update them. This is outside the scope of this posting, but I will follow up with a part 2 that details how to do that, I created an STSASDM command for it.

Creating an Alert Handler

To create an Alert Handler, you need to first create a strong named assembly and then create a class that implements IAlertNotifyHandler. The assembly will be deployed to the Global Assembly Cache as part of a SharePoint Solution Package. The IAlertNotifyHandler interface contains only one method:

public bool OnNotification(SPAlertHandlerParams ahp)

This method is called just before the email is to be sent. The SPAlertHandlerParams object contains all the information about the alert, including the header and body which has already been created using the XML template. The handler method can then inspect the information and decide if the existing email should be sent, or a new one created. To send an email use the SendEmail function:

SPUtility.SendEmail(web, ahp.headers, ahp.body);

Alert emails come in two forms, Immediate and Digest, in my case I only needed to modify the immediate email and so I check the ahp.a.AlertFrequency to see if it was SPAlertFrequency.Immediate if it was not then I send the existing email. The alert email could also be for one of several event types:

SPEventType.Add;
SPEventType.Delete;
SPEventType.Discussion;
SPEventType.Modify;

In my case I only wanted to modify the alert emails for add and modify events.

Once the assembly has been created you will need its public key token to add to the alert template, the easiest way to find it is to add the assembly to the GAC and then display its properties - the public key token is displayed there.

When debugging the code one thing to remember is that even "immediate" alerts are not immediate - they are sent every 5 minutes by and OWSTimer job. So you will need to attach to the OWSTimer process in the debugger. Andrew Connell has some useful VStudio macros that can save you a lot of key strokes and mouse clicks for attaching to the OWSTimer process (See http://andrewconnell.com/blog/archive/2007/01/25/5855.aspx). Another thing you will likely want to do is decrease the time interval for the immediate email from 5 minutes to 1 minute - this will save you lots of waiting time. Use stsadm to chnage the timer job:

stsadm -o setproperty -propertyname job-immediate-alerts -url http://moss/ -propertyvalue "every 1 minutes between 0 and 59"

Having created your assembly you can move onto step 2 - creating the template.

Creating an Alert Template

The first thing to do here is copy the alerttemplates.xml file, if you modify this file directly you run the risk of breaking alerts. The alert templates file can be found in the 12 hive under, TEMPLATE\XML. Once you open this file you will find its huge, around 13K lines, but if you collapse the sections it will become easier to understand. The file contains 14 templates, each one for a different list type, as shown below.

image

Since my clients needs were for a Document Library, I copied the SPAlertTemplateType.DocumentLibrary template. To add an Alert Handler to the template, you need to modify the <Properties> section and add 3 additional nodes which identify the class and the assembly that is to be called, and any properties which are to be passed to the class. For example:

<NotificationHandlerAssembly>Syrinx.Alerts.AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6c60c18cb10a8f1c</NotificationHandlerAssembly>
<NotificationHandlerClassName>Syrinx.Alerts.AlertHandler.ScriptingLibraryAlertNotifyHandler</NotificationHandlerClassName>
<NotificationHandlerProperties/>

The NotificationHandlerProperties can be used to pass a string property to your alert handler class. It can be accessed in the class using ahp.handlerProperties property. In my case I made this an XML string I could more readily parse.

Attaching the Template

Having created the template you now need to update the list of templates in the site collection, this can be done using an stsadm command:

stsadm -o updatealerttemplates -url http://moss -filename "syrinx-alerttemplates.xml“

Having updated the list of templates the next step is to attach the template to the specific list you want to use it. The only way to do this is through code:

            SPAlertTemplateCollection ats = new SPAlertTemplateCollection((SPWebService)_siteCollection.WebApplication.Parent);
            _newTemplate = ats[_alertTemplateName];

            if (_newTemplate == null)
            {
                // We did not find the specified Template.
                throw new Exception("Failed to find template " + _alertTemplateName + "in the template collection.");
            }
            _list.AlertTemplate = _newTemplate;
            _list.Update();

You could add this code as part of a feature receiver, however this would require you to hard code the list name. I chose to create a custom stsadm command that would allow me to attach templates to lists, providing more flexibility.

Once you executed the above code (or similar) to attach the template, new alerts created on the list will use the new template. In my case, the client had a large number of existing alerts configured. These alerts retain the name of the template they were created with and so do not go through the alert handler. To chnage them you need to update the alert definitions; I will cover that in Part 2 along with creating custom STSADM commands.

Information Management Policies: WSS 3.0 vs MOSS

I just wanted to point out a potentially hazardous piece of information everyone out in the land of SharePoint should be aware of.

For those (like us) that are using both SharePoint and WSS 3.0 extensively, and often as platforms for development, it is relatively easy to confuse the two during development and testing, especially when you are deploying all your code and assuming the same basic infrastructure is available to you while ignoring what you consider to be out of the box functionality in the platform.

It is important to realize that Information Management Policies are not supported in WSS 3.0.  Some people believe that Microsoft simple doesn't ship any of the ones that you would normally receive with a full MOSS license.  Items such as the Auditing features, bar coding, labels, etc.  This is all true.  Some people believe that you can, however, write you own custom policies for WSS 3.0.  This is NOT the case.  The underlying Microsoft.Office.Policy assembly is not included with, or installed by WSS 3.0.  When you attempt to register your custom policy you will receive an error about the assembly not being found.

There are a couple lessons here (aren't there always).  The first is to know your product and platform, and keep it in mind as you prepare features and architect your solutions.  The second is to keep your SharePoint development environments (VPCs I hope) as close in software installations and versions to your production environment as possible.

I hope this helps,

-Ryan

Records Center Illustrated Primer - Part III

Now for our final step - to test and enjoy the fruits of our labor. The whole idea is that users can create Analysis Documents anywhere they need to, and not have to know about records management/retention/etc. All they do is send their Analysis Documents to the Records Center, and Records Center will look at the Content Type, determine the Records Routing based on it, and file the document in the correct Document Library in Records Center. From there the Policy we set up will manage the document lifecycle in the Document Library in Records Center, without any user intervention (and with complete auditing/logging to prove we've done what we said we were going to). This makes compliance efforts a lot easier to manage.

 

In a Document Library in your SharePoint site (you can create a new one or use an existing one), we'll need to configure it to allow our new Content Type of Analysis Document. Open the Settings on your Document Library...

 

 rc027

And choose the Advanced Settings link

rc028

Check the radio button for "Allow management of content types"

rc029

Click the link for "Add from existing site content types"

rc030

And add your newly-created Content Type (and any others you want to allow in this Document Library) and click OK.

rc031

 

We're also going to re-order the menu under "New" in this Document Library in order to default to "Analysis Document" first. The link to do this is at the bottom of the Content Types section:

rc032

You can also look at the superset of columns for all Content Types allowed in this Document Library:

rc033 

Now if we select "New" from our Document Library, we can create an Analysis Document

rc034

...but not if you are on Office 2003. Since we created that "Origin" column of metadata that is required, and Office 2003 can't provide it to us, you'll get an error message that tells you to use "Upload Document" instead. During the upload in the browser, SharePoint will prompt you for the Origin, and that metadata will accompany your document into the library.

rc035a

However if you have Office 2007, Word will open and auto-magically gather the required columns right then and there. Pretty slick, and a good reason to upgrade to Office 2007! The combination of Office 2007 and MOSS is greater than the sum of its parts...

rc035b

Once you have created your new Analysis Document, you can use the "Send To" in MOSS to send this document to your Record Center

rc036

You will get a confirmation dialog letting you know your document is now in the Record Center

rc037

If we now switch over to our Record Center we can see that a new folder has been created under our Analysis Documents Document Library. The naming convention for the folder is year, month, day, and time of creation with GMT offset.

rc038

 

Clicking on this folder, we can see that our document has been replicated inside it. Even if the original document library now deletes this document, the copy in Record Center will remain and be managed by our Policy.

rc039

I hope you've enjoyed this series, and please feel free to contact us for help with your SharePoint projects! Email us at info at syrinx dot com, or call us toll-free at 888-579-7469, option 1 on the IVR menu (888-5-SYRINX on your phone).

MOSS Enterprise Search. Part 1

In this series of MOSS Enterprise Search How-To's I'd like to share the knowledge I received from a recent training on setting up the MOSS search engine. In this post I will show how to setup content sources and crawling rules.

Setting up content sources:

1. Navigate to the Search Administration page

- Open SharePoint 3.0 Central Administration web page under  Start -> Administrative Tools and click on SharedServices link on the left side navigation menu under Shared Services Administration

          image

- In Search section click on Search Settings:

image 

2.  Add content sources and start crawling:

- Click on the link to the right of "Content Sources"

image

 

- On the "Manage Content Sources" page click on New Content Source button

image

- Add Content Source Page contains various settings defining the content source you want to setup. 

First you need to add a name for the content source and decide on the content source type;

image

Here I would like to talk about difference between first two content types (SharePoint Sites and Web Sites):

  • They both allow you to specify Start Addresses for crawling; for a  Web Site content type this can include any content, from a single web page to an entire web site; for a SharePoint Sites type this can only include MOSS sites and WSS sites;
  • For Crawl Settings, this is where the difference between the two comes: in a Web Sites Content Source, you can specify that you only want to crawl the server of which you entered the start address, or only crawl the first page, or provide custom crawl settings, where you can specify Server Hops and Page Depth;
    image 
  • Page Depth - number of links to follow within the same hostname; for example if you specify Page Depth of 1, crawler will follow links from the home page and then stop;
  • Server Hops are the number of host name changes that the crawler can make;
  • Another difference is that SharePoint content source allows to crawl a single WSS site collection, which you can't do with a Web Site content source, e.g. if you want to crawl a particular site collection you should put its URL in a SharePoint content source like http://servername.com/sites/yourcollection and select "Crawl only the SharePoint site of each start address". If you put the same exact address for a Web Server content source, it will start crawling from the top address http://servername.com because it's the default for all Sharepoint content:
    image 

And the last step is to create a schedule (or select an existing one) for full and incremental crawls of this content source.

And if you select the "Start full crawl of this content source" check box then the crawl starts right after you click "Ok" button to save the content source settings. Otherwise the crawl will work according to the specified schedule.

In the next post of the series I will show how to create search scopes

Records Center Illustrated Primer - Part II

We resume our series with creating a Document Library in the Records Center to hold our incoming Analysis Documents. When we do a "Send To" from where the document was created, and push it to Records Center, it needs somewhere to land. Go to the Records Center Site we created, and create a Document Library

rc013    ...then...

rc014  ...and...

  rc015 ...which will create...

 

rc016

Next is the important step that distinguishes this document library from a "regular" one - adding the Policy we created that describes how to handle disposition of records contained in it over time. Go to Document Library Settings in our newly created Document Library, and under Permissions and Management choose Information Management Policy Settings

 

rc018

rc019

Specify our Site Collection Policy that we created before, "Delete docs after 3 years" and click OK

rc020

To create a new Record Routing, click New under the Record Routings (there's already a default "Unclassified Records" one, but we want our Analysis Docs to follow a different routing).

rc021

 

rc022

Important Note: The Location indicates the name of the Document Library where the records will be routed to. Be careful and spell this correctly (it would have been nice if this was a drop down where you could choose from a list of all Document Libraries in this site instead). We also created an alias of the singular "Analysis Document" without the "s" on the end, in case people want to refer to the routing in its singular form.

rc023

Now we have the "landing strip" set up for our documents, how to we instruct them to fly there? We need to set up the External Service Connection to allow Web-Services-based submission into our document library, using "Send To". We've been working in your SharePoint site thus far. Now you need to jump over to Central Administration, which may be on a different port/URL at your company. Under the Application Management tab in Central Administration, choose Records center (first entry under External Service Connections)

rc024 

This part is a little tricky. You need to figure out the URL of your Web Services page for your Records Center site. It is the base URL for your site, with /trc/_vti_bin/officialfile.asmx appended to it.  Recall that the base URL is the one we chose back in the "Use the Records Center Template, which is under the Enterprise group. Give your Record Center a name (Records Center, Record Center, etc) and URL." step from Part I of this article series (diagram of that step is repeated here, for reference):

 rc003

For example, your URL might look like http://mysite.com/recordcenter/trc/_vti_bin/officialfile.asmx. This goes in the URL field of "Configure Connection to Records Center". A little sanity check to make sure you have the URL right before you click OK - open a new browser window, and try out the URL in there. You should see the .asmx page come up:

 rc026

You can then cut/copy that URL back to your original browser window and paste it into the URL field in Configure Connection to Records Center, confident that you have the URL right. Click OK and now we're ready to start pushing documents into the Records Center using "Send To"

rc025

In the next part of this series, we'll create a Document Library that the users will use day-to-day, and test their ability to route documents into the Analysis Documents library in Records Center using "Send To".

MOSS 2007 and WSS 3.0 Alternate Access Mapping

I did a three day consulting gig 3 months ago where I installed and configured WSS 3.0, trained them on the basics of document libraries and lists, and converted a spreadsheet with multiple pages into a List so that their users could edit items simultaneously.  They loved the item-level version history because now they could track changes.  To make a long story short, during my exit interview I had mentioned that SharePoint could be accessed directly from home without going through their Citrix VPN if they wanted - they declined.

Yesterday afternoon I got a call from their IT guy and he explained that he is trying to expose the SharePoint portal to the web.  He had already set up DNS for the externally facing domain, opened port 443 in his firewall for SSL access to the SharePoint server, and installed the SSL certificate on the Sharepoint portal’s web application.  When he hit the SharePoint Portal from outside using https://, it appeared to authenticate him, but then redirected him to http:// which was not configured (and they don’t want to open port 80).

The solution to this problem involves SharePoint’s Alternate Access Mapping.  SharePoint stores up to four alternate access paths to the same web application.  This is somewhat like the host headers we are all familiar with; however, it isn’t exactly the same.  Before I explain the differences, and what is going on here, let me show you how to administer AAM’s.

First, open Central Administration, click on the Operations tab, and then click Alternate Access Mappings

 AAMCentralAdmin

Next, click the Edit Public Urls tab

 AAMEditPublic

Once you get to this page, you need to select the Web Application you want to add a public URL to.  In this case I’ve named the portal Client Internal Portal.  Then simply add the external URL in the Extranet field.

AAMNewUrl

 

Content and Structure Reports: Just a CAML Ride Away

For anyone who has looked a little more closely at the Content & Structure section of SharePoint, you'll probably find it doesn't quite do what you were hoping or expected.  You may also have wanted to know how to modify these reports or create your own.  For those not familiar at all with this area, hopefully this post will give you a little advance warning and information.

Site Actions --> Site Settings gets you to the site settings area, from here you can find the content and structure link:

siteadmincands or siteadmincands2

This area is only applicable to sites with the publishing feature turned on.  Anyone familiar with SharePoint will also know that your available settings links will look very different depending on the user logged in, type of site, and features currently enabled.

If you navigate to Content and Structure you will see a familiar tree view on the left where you can select sites, lists, etc.  This gives context to the right-hand window where you can look at views and manipulate content in certain ways.

If you click on view: and choose a report, theoretically all items in the current site context and below should be displayed based on the report.  Instead of going over all these reports, I'll just look at two of them right now, then you'll get the idea about what you can do moving forward.

contentandstructreports

First, let's take a look at the Pending Approval report.  Notice the description?  Here is the CAML that runs this query:

pendapprcaml

This query is basically traversing from the current site down and looking for document library list types with the Approval Status column containing the vlaue "2", which means "Pending".  Here is a sample clip of the XML Schema for this field in the Pages list on one of my publishing sites:

approvalstatuscol

I'm trying to make three points here. One:  The description does not match the results of the query.  The person who submitted the item for approval is definitely not a part of the query.  So, if you think this query will give you all the items you submitted for approval, it won't.

Two:  There is visibly lacking a report that shows you what items are pending approval assigned to you for approval.  We'll cut SharePoint some slack here because assignment of the approval really lives in a task list, not the document library.  A little later I'll show you how we modified the "My Tasks" report to be a little more useful and where can use this to check for items assigned to you for approval.

Three:  These reports are completely customizable, including building your own. I'll go into that next.

If you navigate to your site collection's root site and "view all site content" (/_layouts/viewlsts.aspx) you will see a list called the "Content and Structure Reports".

candslist

If you click on this list you will see the familiar list of available Content and Structure reports living in this list, complete with access to the CAML queries that drive them.  If you click on "Pending Approval" you will see the columns and data used to drive this list.  CAML List Type represents the type of list you are querying.  This field is empty in this particular report, telling the report to run against all lists of type "Document Library".  If you look at the other reports you will quickly notice how they specify certain list types for querying.

candsreportdetails

Now let's create a new report that actually looks at items pending approval that I submitted, so I can quickly see what items I submitted for approval but have yet to be approved.

I click "New Item" and fill out the basic data and write the CAML query.  Here is what my new report list item looks like and below with the CAML query.  There can be no spaces or line returns in the CAML.  If your CAML is greater than 255 characters you need to change the Content and Structure Reports list's CAML Query column to "multiple lines of text" to allow for larger queries.

candsnewcaml

Notice my changes to the original query in order to actually see items I submitted?  I added an AND clause where the Editor field looks at the current UserID.

I've done something similar with the "My Tasks" report as well.  Out of the box this report shows all your current tasks in the contextual site and below, ignoring the status of the task.  Although it's great to see how much work you've accomplished, looking at completed tasks isn't very useful most of the time.  below is just the CAML query I used in order to filter out "Completed" tasks from the list:

candscamlmytasks

Obviously these reports can be powerful tools.  If you have a knack for writing CAML queries you can create some sophisticated and very precise tools for viewing and helping you manage data across your site collection. 

I hope this helps,

-Ryan

Business Intelligence: Not just tools and data

I wanted to point out an interesting article worth a read for those of you looking to implement some Business Intelligence tools, Dashboarding, and KPIs for keeping tabs on your organization's important metrics.

Tom Wailgum of CIO magazine talks in his article about how this can be a confusing undertaking. 

I took particular note of this information because of how I see it impact our consulting business.  Two main points Tom made that stood out to me were the confusing and changing landscapes in this market, and a significant lack of technical expertise to create such applications.  The cost for even licensing some the platforms mentioned in Tom's article can also be enormous.

A significant number of our clients engage us for these exact reasons.  SharePoint represents a reduced initial cost (often many of our clients already own it as part of their Enterprise Agreement with Microsoft) for the platform.  It also enforces much less rigidity in design.  For example, the Business Data Catalog can be used to extract and index data from disparate applications, Excel Services, or simply standard .NET development.  The SharePoint platform represents more aspects of a blank slate in the ability to choose your direction and tolerance for adhering to foreign software products and lifecycles.  It's extensibility and compliance with standard and known development practices make it a logical choice for many organizations.

The final point is that lack of internal expertise or available time has also driven many of our clients to us as well.  Most companies spend the vast majority of their IT budget maintaining current systems, not training and expanding their application base.  This leads them to look externally for a temporary workforce.  They also understand the efficiency gained with bringing in specific skills to complete targeted objectives.

I hope this helps,

-Ryan

Records Center Illustrated Primer - Part I

So you have people at your company storing their documents in SharePoint, are versioning them, and are creating Content Types to help pair metadata to document data and make search more effective. You have things organized into Document Libraries. Then comes the news that you need to comply with [21 CFR Part 11, Sarbanes-Oxley, Basel, fill in your favorite regulation/compliance program here]. You decide on training, retention policies, a rollout procedures, make a checklist for compliance steps, etc. and now want to start leveraging Records Center to manage document lifecycles. There are some resources you can search for, and the best one I saw for listing the steps for setting up Records Center was at http://mdablog.spaces.live.com/blog/cns!B0C40902E1212960!379.entry. I liked this one a lot, but wanted to take it one step further by providing a complete example with screen shots along the way. Approximately 39 screen shots later, we have this series of posts.

Before you begin:

  1. Have your Document Libraries and Content Types set up if possible.
  2. Decide your retention policies
  3. Make sure you don't already have a Record Center set up (only one allowed per SharePoint Farm)
  4. Prefer to try doing this first in a virtual/test environment, before production
  5. Consider bringing in people with experience planning and developing compliance implementations for other companies using SharePoint to help (call us!)

Now the steps to do it, thanks to Marc Anderson's blog for the most complete instructions out there!

1. You need to create a site for Records Center documents to be routed to. There will be one of these per Farm as mentioned above. Start at your top-level home site and create a site  - Site Actions - Create, then Sites and Workspaces link

rc001

Click Create on the left

rc002

Use the Records Center Template, which is under the Enterprise group. Give your Record Center a name (Records Center, Record Center, etc) and URL.

 

rc003

 

2. You need to create the Policy for managing the documents. Go to the top level site settings

rc004

Click on Site Collection Policies

rc005

Click Create to create a new policy.

rc006

Include a name, description, statement, and indicate any auditing that should happen for the document.

 

rc007a

Scroll down and set expiration time/action, and barcode policy if applicable (to help you stay in sync with printed versions of your documents).

rc007b

 

3. If you have not created your Content Types yet, here is an example of doing so. Navigate to your top level home site, and click Site Actions - Site Settings and choose under Galleries, Site content types

rc007c rc007d

 

In the Site Content Type Gallery, click Create

rc008

 

Think of Content Types like subclasses in object oriented programming. You hang them off of a "superclass" like Document, and further refine them to add attributes using columns. Here we create a Content Type called Analysis Document, which will be a Word Doc that has a couple pieces of metadata (columns) that hang off it, Title and Origin. First we create the Content Type

 

rc009

Then we click on Add From new site column to create our Origin column

 

rc012

We'll create a drop-down list called Origin that details how the Analysis document was created - internally at Syrinx, provided by a client, produced by a subcontractor or other vendor on the project, or "other".

rc010

rc011

Now our Content Type is all set.

In the next installment of the series, we'll start with creating the Document Library in the Records Center to hold our incoming documents.