Home | Blog | Screencasts | Projects
# Monday, November 03, 2008

MSDN has a new white paper:

Planning and Monitoring SQL Server Storage for Office SharePoint Server: Performance Recommendations and Best Practices

 

It covers topics such as:

  • Database Autogrowth
  • Storage settings for the recycle bin
  • Using Quota templates
  • List performance
  • Physical Topology Guidance
  • Disk and SAN interfaces
  • Network Topology recommendations
  • Physical Storage recommendations
  • Separating database data files
  • Monitoring, Maintaining, and Troubleshooting (which provides some great performance counters that can be used for monitoring)
  • Disk and SQL recommended practices

In all it is a great resource. The direct download is here.

Monday, November 03, 2008 11:00:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
MOSS | Planning | WhitePaper

There are a number of options that you can use when you define your connection settings in your BDC ADF file:

The authentication methods are:

 

RevertToSelf

Simply uses the application pool account (reverts back to this account) to access the database.

 

   1: <Properties>
   2: <Property Name="AuthenticationMode" Type="System.String">RevertToSelf</Property>
   3: <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
   4: <Property Name="RdbConnection Data Source" Type="System.String">servername</Property>
   5: <Property Name="RdbConnection Initial Catalog" Type="System.String">databasename</Property>
   6: <Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property>
   7: <Property Name="RdbConnection Pooling" Type="System.String">false</Property>
   8: </Properties>

 

PassThrough

Passes the credentials of the calling user, this will only work on a single server install or on a farm if Kerberos is enabled.

 

   1: <Properties>
   2: <Property Name="AuthenticationMode" Type="System.String">PassThrough</Property>
   3: <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
   4: <Property Name="RdbConnection Data Source" Type="System.String">servername</Property>
   5: <Property Name="RdbConnection Initial Catalog" Type="System.String">databasename</Property>
   6: <Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property>
   7: <Property Name="RdbConnection Pooling" Type="System.String">false</Property>
   8: </Properties>

 

SQL Authentication

It is still possible to use SQL Server Authentication, the following example uses the RdbConnection properties for this:

   1: <Properties>
   2: <Property Name="AuthenticationMode" Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAuthenticationMode">
   3: RevertToSelf</Property>
   4: <Property Name="DatabaseAccessProvider" Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAccessProvider">
   5: SqlServer</Property>
   6: <Property Name="RdbConnection Data Source" Type="System.String">servername</Property>
   7: <Property Name="RdbConnection Initial Catalog" Type="System.String">databasename</Property> 
   8: <Property Name="RdbConnection Integrated Security" Type="System.String">false</Property>
   9: <Property Name="RdbConnection User ID" Type="System.String">username</Property>
  10: <Property Name="RdbConnection Password" Type="System.String">password</Property>
  11: </Properties>
  12:  

 

Single Sign On

If your using SSO, this is also supported:

   1: <Properties>
   2: <Property Name="AuthenticationMode" Type="System.String">RdbCredentials</Property>
   3: <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
   4: <Property Name="RdbConnection Data Source" Type="System.String">servername</Property>
   5: <Property Name="RdbConnection Initial Catalog" Type="System.String">databasename</Property>
   6: <Property Name="RdbConnection Integrated Security" Type="System.String">false</Property>
   7: <Property Name="RdbConnection Pooling" Type="System.String">true</Property>
   8: <Property Name="SsoApplicationId" Type="System.String">SSO Application you created</Property>
   9: <Property Name="SsoProviderImplementation" Type="System.String">Microsoft.SharePoint.Portal.SingleSignon.SpsSsoProvider,
Microsoft.SharePoint.Portal.SingleSignon, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Property>
  10: </Properties>

 

The MSDN documentation can be found here.

Monday, November 03, 2008 10:25:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
BDC | MOSS
# Tuesday, October 28, 2008

The BDC isn’t just limited to data located in a database, it’s most powerful feature is its ability to call webservices. I previously posted a brief description of the types of webservices are easily consumed by the BDC.

The key to easily calling webservices from the BDC first starts with an understanding of the types of methods that the BDC supports:

  • Finder 
  • Specific Finder
  • IDEnumerator

If we take the common example of getting customers from a webservice we might can start thinking about the way we create the webservice so that it doesn’t become a painful exercise.

The first method we should think about is something that can return the primary key (or ID) of our data:

So a method like:

GetCustomerIDs  - This will return customer ID’s and will become our IDEnumerator

So the BDC will next need a method that will accept an ID that was returned by our GetCustomerIDs method above.

GetCustomerByID  - This will become a Specific finder method, the naming ‘specific’ really gives the game away, it’s specifically returning data based on an ID.

The final method is a generic finder method that can be used by the Business Data List webpart:

GetCustomers – This becomes a finder method, we can have more of these methods with each one returning a different subset of data as needed.

 

It’s fairly easy to now create a BDC Application Definition File (ADF) using a tool like BDC Meta-Man. But you also need to remember that the ADF references a .NET assembly. This assembly is the proxy to the webservice, this proxy is the exact same proxy that we get automatically generated for us by Visual Studio when we add a web reference.

So you can create a proxy that will be used by the BDC, you just create a web reference in visual studio and compile that into a signed assembly and make sure the ADF references this assembly correctly.

Once you perform the two steps of creating the ADF and corresponding proxy classes, your well on your way to using the BDC via webservices.

Tuesday, October 28, 2008 1:10:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
BDC | MOSS
# Thursday, October 23, 2008

One of the cool things that MOSS offers is the ability to display the people search results ordered by social distance. You can see what result format was returned by looking at the search action links web part:

 

socialdisresults

The default people search results view can be changed in the Core results web part:

 

coreresultswp

 

The MSDN SharePoint blog has a detailed post which outlines how the colleague connections are formed:

  • Immediate colleagues which are formed using the manager profile field.
  • Colleagues added by you
  • Suggested colleagues

It’s also an interesting read to find out some small details like:

  • The first 3 pages of search results are grouped by colleague-ness: first your colleagues appear, then colleagues of your colleagues, then everyone else.
  • Within each group, the ordering is still by relevance.
  • When paging through results, another 3 pages of results will be grouped once you reach page 4, then page 7, etc.

 

Overall I think the feature works extremely well, although I’ve seen some users struggle with the feature, these users were typically expecting the results to be in alphabetical order like their previous pre-MOSS system. While I don’t agree with the concept since the results are returned by relevance (but in a social context) it is possible to sort the results alphabetically, Paul Galvin has posted some XSLT that does this. Remember that this is done outside of the search engine itself, so the XSLT is only going to sort the results per page. So its possible to have page 1 contain 10 results ordered alphabetically, then page 2 will contain 10 results that are again sorted alphabetically, which might cause problems to some users.

I think ultimately these users just need a little bit of training to understand the social distance format. Just like any search engine if you don’t get the results you are looking for on the first page, I really think you need to refine your search. If your just looking for a colleagues details the social distance is fantastic and saves lots of time, my experience is that I use the people search 90% of the time to find colleagues, of course your situation may be different.

Thursday, October 23, 2008 7:39:14 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
MOSS | Search
# Tuesday, October 14, 2008

I previously blogged about using the BDC with MOSS user profiles and how to set that whole process up. Well I thought that I might write a little about the BDC application definition file (ADF) that is imported into MOSS and is used by the BDC to generate the meta-data and to ultimately connect to the data source.

An ADF file contains metadata describing entities and methods to populate those entities.

These are the methods that are of interest to us, all have nice relevant names:

 

IDEnumerator – These methods can perform filtering and can be passed parameters, the idea is that it returns an ID (and a timestamp if possible), as it’s name implies it is used to enumerate all the ID’s (or primary keys). In the context of the profile import, if your key is say, an Active Directory email address, then the IDEnumerator should return the email address field.

Specific Finder – This method accepts an ID and returns just the information related to that ID. You’ll probably create a number of these using different filter descriptors.

 

Now that you have an idea of what the methods are and how they operate you can design web services that are low friction for the BDC.

You’ll need a web service that returns a list of ID’s (for the IDEnumerator), you’ll need a second webservice that accepts the same ID’s that were returned by the first method, this second method will comprise your Specific Finder methods.

Also don’t create trouble for yourself by building webservices that accept a large number of parameters, you’ll regret it, just keep it simple. The guys that developed the fantastic BDC Meta-Man product also have the same advice.

 

I’ve provided the SQL create statement and ADF file here.

Tuesday, October 14, 2008 9:05:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
BDC | code | MOSS
# Sunday, October 05, 2008

MOSS 2007 has the option to use a dedicated web front end server for crawling content:

Dedicatedcrawler

 

Why would you want to do this:

 

Advantages:

  • Search doesn’t compete with the end users – Large environments that need to crawl constantly can cause more traffic than normal user load, you don’t really want your users to experience slow pages just because your doing an index? By using a dedicated web front end that isn’t part of the load balanced cluster, your indexing won’t impact your users as much (I say as much, because you still need to think about the impacts of the database server).
  • Easy to move the WFE into the load balanced cluster – It’s a rather crude disaster recovery method, but it’s not that hard to move this box into the load balanced cluster if you really need the extra capacity or if one of your other servers fail. After all it’s just a normal web front end, but one that is reserved for the indexer.
  • Perfect place to run a backup central admin – You should always try to have more than one server running central admin (on a large farm anyway), that way if your main central admin server goes down, you still have a way to manage the farm.

 

Disadvantages:

  • More hardware – The obvious disadvantage to having an extra machine is the requirement of more hardware, which also means:
  • More cost – New hardware is an additional cost, but now that you have an idea of the advantages it brings, you can make a more informed decision.

 

 Joel has some other tips such as adding a robots.txt to servers that you don’t wish to participate in the indexing process.

Sunday, October 05, 2008 7:24:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
configuration | MOSS | Sharepoint | Search
# Friday, October 03, 2008

The next integration method that I want to discuss is the collection of data. As a web developer you’ve no doubt been asked to create a form that does X a number of times, you might even have created some tools to aide in this, it’s pretty common. So now that you’ve moved across to the dark side of MOSS development we need to break your thinking, if you want to create a form, first have a look at Microsoft InfoPath, InfoPath files can be published to MOSS running the InfoPath Forms Service.

 

The benefits to this approach are:

  • Less development – I won’t go as far to say that even the worst coder on your team could use this tool, that guy can’t do anything, but for simple stuff it’s not too hard to get your head around.
  • Central management of forms – You can easily keep track of your forms, how many times have you written a form that has already been developed? But seriously because each form is a content type, you can manage the metadata of a form from a single location, regardless of how many libraries you’ve added the content type to.
  • Can easily use existing MOSS features - This is the biggest feature, you can easily add workflow capabilities or publish your results to a list, I bet most of your forms currently just send an email and get written to a database.

The disadvantages are:

  • It requires a different way of thinking - This might not be a bad thing, but some large organisations have teams of programmers who spend 90% of their time doing some sort of forms based programming. It might be a hard sell for these guys.
  • Anonymous access might cause some issues – I’ve seen a few issues around anonymous access to forms, it’s by no means a show stopper, but you should think about this before you deploy.

I think the benefits far out weigh the disadvantages, in any case hopefully the next time you hear a developer say they’ll create a web part for a form, you’ll think about it a little more carefully.

Friday, October 03, 2008 4:04:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
Integration | MOSS | Sharepoint
# Wednesday, September 24, 2008

Just a quick tip, if your crawling external sources with the MOSS (or Enterprise Search), you might find that your crawl doesn’t finish or hangs, it might be worthwhile checking to see if the site you are crawling has a calendar with links:

 

image

 

You will need to determine the URL and then add a crawl rule to exclude that path, the crawler will see an infinite number of pages (it thinks each date and next link is a separate page).

Wednesday, September 24, 2008 1:17:00 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
MOSS | Search | Sharepoint
# Tuesday, September 23, 2008

I recently had a project where I needed to bind some business objects to a SPGridView in a web part, which on its own is trivial, but I also needed to create the columns for the SPGridView on the fly, since a number of business objects could be rendered in this control.

The main problem was the naming of these columns, if I just bound them directly to the Grid, I would get the ugly naming of my properties (I say it’s ugly, it’s actually pretty awesome if your a developer, but those pesky end users like pretty names).

The sample grid looks like this by default:

 

grid-without

 

So what I came up with isn’t exactly new or innovative, I created a custom attribute called Alias:

 

    public class AliasAttribute : System.Attribute
    {
        protected string[] aliasName;

        public AliasAttribute(params string[] alias)
        {
            this.aliasName = alias;
        }

        public string[] Alias
        {
            get { return aliasName; }
            set { aliasName = value; }
        }
    }

 

This attribute gets applied to each property on your business object with a pretty name:

 

        [Alias("Internet URL")]
        public string InternetAddress
        {
            get { return internetAddress; }
            set { internetAddress = value; }
        }

 

Now the code that performs the binding looks for properties with a custom attribute and pulls out the alias as the HeaderText:

BoundField newBoundField = new BoundField();
newBoundField.HeaderText = Helpers.GetPropertyAlias(field.Trim());
newBoundField.DataField = field.Trim();
grid.Columns.Add(newBoundField);
public static string GetPropertyAlias(string propertyName)
{
    //Change the next line for your business object ..
    PropertyInfo[] propInfos = typeof(BusinessObject).GetProperties();

    foreach (PropertyInfo propInfo in propInfos)
    {
        if (propInfo.Name.ToUpper().Equals(propertyName.ToUpper()))
        {
            object[] attribs = propInfo.GetCustomAttributes(typeof(AliasAttribute), true);
            foreach (object attrib in attribs)
            {
                if (attrib is AliasAttribute)
                {
                    AliasAttribute alias = (AliasAttribute)attrib;
                    //return the alias
                    return alias.Alias[0];
                }
            }
        }
    }

    //if we don't find the custom attribute, just return the same value we passed in
    return propertyName;
}

 

The end result is a nice pretty grid:

 

Grid-With

 

A sample project can be found here.

Tuesday, September 23, 2008 10:20:00 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | MOSS | Sharepoint
Statistics
Total Posts: 134
This Year: 0
This Month: 0
This Week: 0
Comments: 20