Within a SharePoint farm configuration (multiple servers), the SharePoint Health Analyzer will first complain that the SPTraceV4 account should not be running as a local service. If you manually fix this by setting a domain account for the trace service (on each server) and restarting the service, sometimes you will still get the message 'Built-in accounts are used as application pool or service identities' within the Health Analyzer. To fix this, do the following:
1) Create the Trace Account (e.g. DOMAIN\svc-SP_TRC) as a managed account.
2) Start up the SharePoint 2010 Management Shell in administrator mode
3) Type the following Powershell script:
$servicename = "SPTraceV4"
$managedaccountname = "DOMAIN\svc-SP_TRC"
$farm = Get-SPFarm
$SPTimerv4 = $farm.Services | Where {$_.Name -eq $servicename}
$SPTimerV4NewAccount = Get-SPManagedAccount $managedaccountname
$SPTimerv4.ProcessIdentity.CurrentIdentityType = "SpecificUser"
$SPTimerv4.ProcessIdentity.ManagedAccount = $SPTimerV4NewAccount
$SPTimerv4.ProcessIdentity.Update()
4) Goto to each server in the farm and restart the tracing service. Then do an IISRESET /noforce on each SharePoint Server
5) Open up Central Administration, view the problem report and re-analyze the built-in accounts Health Analyzer message.
6) Close the report message and refresh the page. The error should now be gone.
7) If you have moved your logs to another (e.g. non-System) drive, on the directory where logs are to be written to, ensure that the nominated domain Trace account has full read/write permissions to it. You may have to restart the trace service and do an IISRESET again to notice that activity is now being written to the LOGS directory. Note that this approach also fixes the issue where you see lots of log file entries, all 0KB in length.
Tuesday, March 29, 2011
Thursday, September 23, 2010
SharePoint 2010 Branding Frustrations
This is not a solution to anything, just a place to vent my anger. I hate it how SharePoint 2010 page layouts go against basic CSS best practices. The biggest issue for me at the moment is that the page layouts are rendered once again in nested tables and that nearly every web part zone has an ID of "_invisibleIfEmpty". Come on guys! It is not that hard!
Wednesday, July 21, 2010
Search Delegate Control in SharePoint 2010
Currently I am in the process of upgrading a SharePoint 2007 Internet site to 2010. One of the things that had me stuck initially was that after I did the upgrade and created a 2010 specific master page, my search delegate control was not showing up. I finally figured out that search delegate controls must have the Web Application feature scope in order to work. For my 2007 site, it was using Site Collection level scope.
Monday, May 24, 2010
Prerequisite install gotchas when installing with no Internet connectivity
I am installing a SharePoint 2010 environment at the moment for a client where Internet access from the SharePoint box is blocked. I have found that even though I installed the compulsory prereq components, unless you install all of the prereqs, the prerequisite install function fails (e.g even though the speech components are optional, the prereq installer will fail if it doesn’t find them already installed). A bigger issue is that Microsoft currently has 3 versions of the prerequisite item 'SQL 2008 R2 Analysis Services ADOMD.NET' available, where only the one at http://go.microrosft.com/fwlink/?LinkID=160390 will work because of the registry settings it makes (which the prereq installer looks for). The correct version of SQLSERVER2008_ASADOMD10.msi is 6924KB. The versions that don’t work are http://go.microsoft.com/fwlink/?LinkID=188442&clcid=0x409 (SQL 2008 R2, which is 7099KB) or http://go.microsoft.com/fwlink/?LinkId=130651 (SQL 2008, which is 4416KB).
Thursday, May 28, 2009
Performing Long Running Tasks in SharePoint
Occasionally you may have a custom action that takes a while to run. On one of my recent projects we had just this need. Basically we wanted to convert an ordinary out of the box document library into a 'Projects' Document library. This involved setting the properties of the library (e.g. versioning, content types, enforce checkout etc), adding new content types to the library, setting up workflows for the library and applying event handlers.
The way that we did this was to create an Application page (under layouts), which got called by the custom action. Within the OnLoad of this page, we had the following:
using (SPLongOperation operation = new SPLongOperation(this.Page))
{
try
{
operation.LeadingHTML = "Convert to Project Documents library";
operation.TrailingHTML = "Please wait while your document library is being prepared for project use.";
operation.Begin();
// your code goes here
operation.End(string.Format("{0}&ConversionStatus={1}", this.CurrentRequestUrlAndQuery, FormSubmitStatus.Success.ToString()));
}
catch (Exception ex)
{
// record the error
operation.End(string.Format("{0}&ConversionStatus={1}", this.CurrentRequestUrlAndQuery, FormSubmitStatus.Fail.ToString()));
}
}
How easy is that? SharePoint Rocks!
The way that we did this was to create an Application page (under layouts), which got called by the custom action. Within the OnLoad of this page, we had the following:
using (SPLongOperation operation = new SPLongOperation(this.Page))
{
try
{
operation.LeadingHTML = "Convert to Project Documents library";
operation.TrailingHTML = "Please wait while your document library is being prepared for project use.";
operation.Begin();
// your code goes here
operation.End(string.Format("{0}&ConversionStatus={1}", this.CurrentRequestUrlAndQuery, FormSubmitStatus.Success.ToString()));
}
catch (Exception ex)
{
// record the error
operation.End(string.Format("{0}&ConversionStatus={1}", this.CurrentRequestUrlAndQuery, FormSubmitStatus.Fail.ToString()));
}
}
How easy is that? SharePoint Rocks!
Creating SharePoint Timer Jobs
In my current project, I have been developing a bunch of functionality around project space provisioning. As part of this, I decided that as there were a lot of activities to be performed when creating and configuring the new site, developing a SharePoint Timer Job was the best option.
So lesson learnt #1 - You can't programmatically create a timer job from a site collection feature. The reason for this is that typically the application pool that looks after the site does not have permission to write to the configuration database. Creating a Timer Job requires you to be able to write the timer job definition into the configuration database, so if your application pool doesn't have the rights, then the creation of the job will fail.
So basically you have to create a Web Application level feature (i.e. activated through Application Management tab of Central Admin) with a feature receiver method that creates the timer job. E.g.
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="2DEA0BA9-A8D1-4475-AD0B-8FE25EBF65A2"
Title="Project Spaces Provisioning Timer Job"
Description="Add timer job required for project space provisioning."
Version="12.0.0.0"
Hidden="FALSE"
Scope="WebApplication"
DefaultResourceFile="core"
ReceiverAssembly="Collaboration.Projects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d76123a549458435"
ReceiverClass="Collaboration.Projects.FeatureCode.ProjectProvisioningTimerJob"
xmlns="http://schemas.microsoft.com/sharepoint/">
<elementmanifests>
</feature>
Creating the timer job in code is actually quite simple. Below is the feature activation/deactivation code:
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Collaboration.Projects.Provisioning;
namespace Collaboration.Projects.FeatureCode
{
///
/// Creates the timer job that runs the site creation process for confirmed requests in the provisioning request list
///
public class CollabProjectProvisioningTimerJob : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWebApplication application = properties.Feature.Parent as SPWebApplication;
DeleteProvisioningJob(application);
// install the job
ProjectSpaceCreationTimerJob provisioningJob = new ProjectSpaceCreationTimerJob(application);
SPMinuteSchedule schedule = new SPMinuteSchedule() { BeginSecond = 0, EndSecond = 59, Interval = 30 };
provisioningJob.Schedule = schedule;
provisioningJob.Update();
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
DeleteProvisioningJob(properties.Feature.Parent as SPWebApplication);
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
///
/// Deletes the provisioning job if it exists
///
///
private void DeleteProvisioningJob(SPWebApplication application)
{
foreach (SPJobDefinition job in application.JobDefinitions)
{
if (job.Name == ProjectSpaceConstants.ProvisioningJobName)
job.Delete();
}
}
}
}
Now the ProjectSpaceCreationTimerJob class just inherits from SPJobDefinition. Below is a code snippet (note that the Execute method is the actually code that gets executed when the job runs).
using System;
using System.Net;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Collaboration.Projects.Resources;
using Collaboration.Provisioning;
using Collaboration.Common;
using System.Text;
namespace Collaboration.Projects.Provisioning
{
public class ProjectSpaceCreationTimerJob : SPJobDefinition
{
public ProjectSpaceCreationTimerJob() : base() { }
public ProjectSpaceCreationTimerJob(SPWebApplication web)
: base(ProjectSpaceConstants.ProvisioningJobName, web, null, SPJobLockType.Job)
{
this.Title = ProjectSpaceConstants.ProvisioningJobName;
}
public override void Execute(Guid targetInstanceId)
{
// your code goes here
base.Execute(targetInstanceId);
}
}
}
Hope this helps. I've written it down here so that I remember it in the future.
So lesson learnt #1 - You can't programmatically create a timer job from a site collection feature. The reason for this is that typically the application pool that looks after the site does not have permission to write to the configuration database. Creating a Timer Job requires you to be able to write the timer job definition into the configuration database, so if your application pool doesn't have the rights, then the creation of the job will fail.
So basically you have to create a Web Application level feature (i.e. activated through Application Management tab of Central Admin) with a feature receiver method that creates the timer job. E.g.
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="2DEA0BA9-A8D1-4475-AD0B-8FE25EBF65A2"
Title="Project Spaces Provisioning Timer Job"
Description="Add timer job required for project space provisioning."
Version="12.0.0.0"
Hidden="FALSE"
Scope="WebApplication"
DefaultResourceFile="core"
ReceiverAssembly="Collaboration.Projects, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d76123a549458435"
ReceiverClass="Collaboration.Projects.FeatureCode.ProjectProvisioningTimerJob"
xmlns="http://schemas.microsoft.com/sharepoint/">
<elementmanifests>
</feature>
Creating the timer job in code is actually quite simple. Below is the feature activation/deactivation code:
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Collaboration.Projects.Provisioning;
namespace Collaboration.Projects.FeatureCode
{
///
/// Creates the timer job that runs the site creation process for confirmed requests in the provisioning request list
///
public class CollabProjectProvisioningTimerJob : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWebApplication application = properties.Feature.Parent as SPWebApplication;
DeleteProvisioningJob(application);
// install the job
ProjectSpaceCreationTimerJob provisioningJob = new ProjectSpaceCreationTimerJob(application);
SPMinuteSchedule schedule = new SPMinuteSchedule() { BeginSecond = 0, EndSecond = 59, Interval = 30 };
provisioningJob.Schedule = schedule;
provisioningJob.Update();
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
DeleteProvisioningJob(properties.Feature.Parent as SPWebApplication);
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
///
/// Deletes the provisioning job if it exists
///
///
private void DeleteProvisioningJob(SPWebApplication application)
{
foreach (SPJobDefinition job in application.JobDefinitions)
{
if (job.Name == ProjectSpaceConstants.ProvisioningJobName)
job.Delete();
}
}
}
}
Now the ProjectSpaceCreationTimerJob class just inherits from SPJobDefinition. Below is a code snippet (note that the Execute method is the actually code that gets executed when the job runs).
using System;
using System.Net;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Collaboration.Projects.Resources;
using Collaboration.Provisioning;
using Collaboration.Common;
using System.Text;
namespace Collaboration.Projects.Provisioning
{
public class ProjectSpaceCreationTimerJob : SPJobDefinition
{
public ProjectSpaceCreationTimerJob() : base() { }
public ProjectSpaceCreationTimerJob(SPWebApplication web)
: base(ProjectSpaceConstants.ProvisioningJobName, web, null, SPJobLockType.Job)
{
this.Title = ProjectSpaceConstants.ProvisioningJobName;
}
public override void Execute(Guid targetInstanceId)
{
// your code goes here
base.Execute(targetInstanceId);
}
}
}
Hope this helps. I've written it down here so that I remember it in the future.
Thursday, November 06, 2008
Access is denied. Check that the Default Content Access Account has access to this content.
I had the following error on an Extranet site that I setup recently:
The start address <https://abc.def.com> cannot be crawled.
Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (0x80041205).
I had read on other blogs that the trick was to login to the Index Server as the MOSS Search account, check that you can access the site, and verify the proxy/exclusions had been setup correctly. This normally works, but it didn't for me this time. And it certainly wasn't permissions as the search account had full read access to the site through the Application Policy interface within Central Admin.
In the end, I found that a registry change and a reboot of the server was required to fix it. See http://support.microsoft.com/kb/896861. I used Method 1 (Disable loopback check) to fix the problem. That is:
1. Click Start, click Run, type regedit, and then click OK.
2. In Registry Editor, locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
3. Right-click Lsa, point to New, and then click DWORD Value.
4. Type DisableLoopbackCheck, and then press ENTER.
5. Right-click DisableLoopbackCheck, and then click Modify.
6. In the Value data box, type 1, and then click OK.
7. Quit Registry Editor, and then restart your computer.
I hope this helps. It frustrated the living daylights out of me at the time.
The start address <https://abc.def.com> cannot be crawled.
Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (0x80041205).
I had read on other blogs that the trick was to login to the Index Server as the MOSS Search account, check that you can access the site, and verify the proxy/exclusions had been setup correctly. This normally works, but it didn't for me this time. And it certainly wasn't permissions as the search account had full read access to the site through the Application Policy interface within Central Admin.
In the end, I found that a registry change and a reboot of the server was required to fix it. See http://support.microsoft.com/kb/896861. I used Method 1 (Disable loopback check) to fix the problem. That is:
1. Click Start, click Run, type regedit, and then click OK.
2. In Registry Editor, locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
3. Right-click Lsa, point to New, and then click DWORD Value.
4. Type DisableLoopbackCheck, and then press ENTER.
5. Right-click DisableLoopbackCheck, and then click Modify.
6. In the Value data box, type 1, and then click OK.
7. Quit Registry Editor, and then restart your computer.
I hope this helps. It frustrated the living daylights out of me at the time.
Monday, April 28, 2008
Fixing the Search Settings Forbidden (403) Error
Last week I installed hotfix 941653 and hotfix 950292 (post SP1) to a client site to fix the dreaded Error: 'length' is null or not an object that occurs with Office 2003 Standard edition and MOSS Content Types. Unfortunately, not only did the problem remain (i.e. the hotfix fixed nothing), but I started to get 403 (Forbidden) errors when I tried to navigate to Search Settings page.
To fix this problem, I had to do the following:
From the index server (I've got a front-end web server and a backend index server, both 64 bit):
stsadm -o search -action stop -f
then I did
stsadm -o search -action start -role indexquery
then I did a:
stsadm -o execadmsvcjobs
Then I went back to the front end web server, navigated to the Shared Services Admin page, selected the SSP site, then from its context menu selected 'Edit Properties'. Then from the screen I reselected what the Index server was. After this, on the front end server I did a stsadm -o execadmsvcjobs. Then search started working again (but as the index was blown away, I had to do a full reindex).
To fix this problem, I had to do the following:
From the index server (I've got a front-end web server and a backend index server, both 64 bit):
stsadm -o search -action stop -f
then I did
stsadm -o search -action start -role indexquery
then I did a:
stsadm -o execadmsvcjobs
Then I went back to the front end web server, navigated to the Shared Services Admin page, selected the SSP site, then from its context menu selected 'Edit Properties'. Then from the screen I reselected what the Index server was. After this, on the front end server I did a stsadm -o execadmsvcjobs. Then search started working again (but as the index was blown away, I had to do a full reindex).
Friday, April 04, 2008
Fiddler2 and Pipeboost are your friend!
To my surprise this week, one of the sites that I am helping with went live (deployed by the customer). One of the comments from the customer was 'it is quite slow'. Well to help identify what was going on, I brought out my trusty friends - Fiddler2 and Pipeboost.
Fiddler2
Basically, Fiddler is an IE add-on that monitors what comes down the wire to the browser whenever you request a page. In includes all the details about what types of files are downloaded (jpg, swf, css, js etc) and how long it takes. It even provides a pie chart to show what file types are causing the biggest payload. My first test on the site was with all of my cache cleared (so that I measure the performance of the first time visitor to the site). Yes it was definitely slow. My second request was done without clearing the cache. In this report however, it showed that although the flash files were being cached, All of the images stored in the SiteCollectionImages library were not.
So Fiddler helped me to identify that the BlobCache had not been configured on the server. This is a setting in the Web.Config file. It helps IIS to store images that are stored in SharePoint (and therefore in the backend database) to the local file system. Thus making subsequent requests for those resources a whole lot quicker (because a SharePoint database request is not required). The syntax for BlobCache is as follows:
Pipeboost (www.pipeboost.com)
Pipeboost helped me to identify whether or not IIS Compression had been configured on the production server. As most of you would know, browsers such as IE can handle compression. There is a handshake that goes on between the server and the browser to see whether the browser supports compression. If it does, then IIS compresses the contents (thus reducing the payload) and sends it to the browser, where it is decompressed and displayed to the user. There are two types of content that can be compressed - Static (like images) and Dynamic (like ASPX pages). Static compressioncan compress the file as well as stores it in the Temporary Internet Files directory, so that it can be served up quicker next time. Dynamic waits for the ASPX to return its content, then it just sends that page compressed back to the browser (i.e. it doesn't store it in the Temporary Internet Files location).
There is a great article at http://www.dotnetjunkies.com/Article/16267D49-4C6E-4063-AB12-853761D31E66.dcik that explains how to setup IIS Compression. At the end of this article, it talks about Pipeboost, which can tell you whether or not the payload returned from the web server is compressed (i.e. via IIS Compression).
Fiddler2
Basically, Fiddler is an IE add-on that monitors what comes down the wire to the browser whenever you request a page. In includes all the details about what types of files are downloaded (jpg, swf, css, js etc) and how long it takes. It even provides a pie chart to show what file types are causing the biggest payload. My first test on the site was with all of my cache cleared (so that I measure the performance of the first time visitor to the site). Yes it was definitely slow. My second request was done without clearing the cache. In this report however, it showed that although the flash files were being cached, All of the images stored in the SiteCollectionImages library were not.
So Fiddler helped me to identify that the BlobCache had not been configured on the server. This is a setting in the Web.Config file. It helps IIS to store images that are stored in SharePoint (and therefore in the backend database) to the local file system. Thus making subsequent requests for those resources a whole lot quicker (because a SharePoint database request is not required). The syntax for BlobCache is as follows:
Pipeboost (www.pipeboost.com)
Pipeboost helped me to identify whether or not IIS Compression had been configured on the production server. As most of you would know, browsers such as IE can handle compression. There is a handshake that goes on between the server and the browser to see whether the browser supports compression. If it does, then IIS compresses the contents (thus reducing the payload) and sends it to the browser, where it is decompressed and displayed to the user. There are two types of content that can be compressed - Static (like images) and Dynamic (like ASPX pages). Static compressioncan compress the file as well as stores it in the Temporary Internet Files directory, so that it can be served up quicker next time. Dynamic waits for the ASPX to return its content, then it just sends that page compressed back to the browser (i.e. it doesn't store it in the Temporary Internet Files location).
There is a great article at http://www.dotnetjunkies.com/Article/16267D49-4C6E-4063-AB12-853761D31E66.dcik that explains how to setup IIS Compression. At the end of this article, it talks about Pipeboost, which can tell you whether or not the payload returned from the web server is compressed (i.e. via IIS Compression).
Strange Behaviour when Editing a SharePoint Search Resuls Page
As part of the the work that I do with my own company (MS-Advantage), I get to work on a lot of interesting projects, as well as work with a lot of interesting partner/development companies.
For example, currently I am doing some work on the side with a Graphic Design company who have been charged with developing the branding for a global web site. I basically provide them with guidance on how to best use and develop with SharePoint, while they do the leg work of developing the master pages and page layouts.
While I was working on the project yesterday, the customer indicated that the Search results page was returning sites and list information that they did not want to appear. To resolve the issue, I went into the search results page, edited the core results web part to add an additional query to the results (Query2 and isdocument:1, which basically says 'only show pages or documents').
Well I checked in a draft version of the search results page and started to test that it worked. As the results returned was exactly what I was after, I then published the page (so that it would get picked up in that night's content deployment job). After publishing the page however, every time I navigated to the search results page (even without providing a search keyword), the search results that I had previously used while testing were still being displayed. I tried to roll back to previous versions, but that didn't help. In the end I had to open up the page in SharePoint Designer, AND TO MY HORROR SharePoint had injected the results HTML into my web page. Once I deleted this and saved it, I was then able to re-publish the page.
For example, currently I am doing some work on the side with a Graphic Design company who have been charged with developing the branding for a global web site. I basically provide them with guidance on how to best use and develop with SharePoint, while they do the leg work of developing the master pages and page layouts.
While I was working on the project yesterday, the customer indicated that the Search results page was returning sites and list information that they did not want to appear. To resolve the issue, I went into the search results page, edited the core results web part to add an additional query to the results (Query2 and isdocument:1, which basically says 'only show pages or documents').
Well I checked in a draft version of the search results page and started to test that it worked. As the results returned was exactly what I was after, I then published the page (so that it would get picked up in that night's content deployment job). After publishing the page however, every time I navigated to the search results page (even without providing a search keyword), the search results that I had previously used while testing were still being displayed. I tried to roll back to previous versions, but that didn't help. In the end I had to open up the page in SharePoint Designer, AND TO MY HORROR SharePoint had injected the results HTML into my web page. Once I deleted this and saved it, I was then able to re-publish the page.
SharePoint Deployment Guide and Checklist
While I was at the SharePoint Conference in Seattle, I attended a session on 10 Steps to Governance (presented by Brian Cook and Joel Olesen). Just before the session started, Microsoft were handing out a little pocket guide called the SharePoint Deployment Guide and Checklist. It contained lots of useful information about governance plans, deployment checklists and deployment team roles.
When I showed it to a few guys I work with, they thought 'hey, where can I get a copy'. Well, I found it online at http://office.microsoft.com/download/afile.aspx?AssetID=AM102552101033.
So enjoy!
When I showed it to a few guys I work with, they thought 'hey, where can I get a copy'. Well, I found it online at http://office.microsoft.com/download/afile.aspx?AssetID=AM102552101033.
So enjoy!
Sunday, March 09, 2008
SharePoint Conference catchup with Heather Solomon
While I was at the SharePoint Conference in Seattle, I caught up with Heather Solomon (SharePoint branding MVP) from SharePointExperts.com.
Below are some of the tips and tricks that we discussed (and some of my own tips):
Below are some of the tips and tricks that we discussed (and some of my own tips):
- Explore using CSS to customize the OOTB navigation controls before you go out venturing on creating your own.
- Incorporate the @import to include your CSS in your Master Pages. Heather's opinion is that you should only use the alternate CSS option to tweak particular areas.
- Store your CSS and branding images on the web server. Images go in their own directory under 'Template\Images'. The CSS file should be stored inside a directory under 'Styles' (under the 12 hive).
- Package your branding in Solution Package/Feature. Check out
http://codeplex.com/stsdev for a Visual Studio Project Template for this (developed by Ted Patterson and Andrew Connel) - On the development machine, turn off custom errors in the web.config (
set Callstack = False. Set CustomErrors=Off) - Apart from using Alternate Stylesheets, Themes can also be used to help brand the Application.master template (remember you can't actually change the HTML structure though)
- Meeting Workspaces do not pick up your custom master page. There is some special code in the meeting workspace master page that renders the multiple meeting navigation that you normally see on the left hand side. You need to create a separate masterpage for the meeting workspace, then create a feature stapling to the meeting workspace to change its default master page.
- Blogs and Wikis use different styles, so be careful
- Take advantage of contextual selectors (e.g. div#mydiv ms-SPLink {...} )
- The word specificity (which I can never pronounce in meetings) basically means that a number is derived from the way in which an element is styled. Sometimes you see styles overriding others when you see things like class names sitting right next to the element. Think of the number as A-B-C. For each ID that you use, you add 1 to A. For every class you use, you add 1 to B. Then for a base class definintion, you add 1 to C. So p#largetext ul.mylist li has a specificity of 1-1-1 (or 111). If I just set a style on li (corresponding to a specificity of 1), the specificity with the highest number would be applied to the element.
- Don't go crazy with classes. Use IDs more often and classes sparingly. That way in your CSS, you can use contextual selectors to define a style. E.g. div#mydiv table tr td a { font-family: Verdana }. In this example I haven't used classes at all. I am basically finding the element by starting at the ID level first.
- Heather mentioned that in the past, she has seen SharePoint Designer take grouped styles (e.g. h1, h2, h3 ....) and separate them to h1 {} h2 {} etc (so adding more lines than what is necessary). Heather uses 'Top Style Pro 3.5' to author her CSS, but she hasn't tested opening up a CSS stored in the 'Style Library' areas (remember that she prefers to have the CSS stored on the web server).
Wednesday, March 05, 2008
Fab 40 Application Templates and Role-based My Site Templates Author
Tonight's SharePoint Conference's social evening was at the Museum of Flight in Seattle. During the night, I managed to catchup with Bob Sutton, Senior Product Manager within the SharePoint product group. After having a couple of drinks together (part of it on me unfortunately), we started to discuss the Application templates, and in particular the role-based My Site templates. How stupid did I feel when he said 'oh yeah, I wrote all of that!'. So now when I have questions (particularly about the My Site templates) I can go directly to the source. Thanks Bob!
I also got to meet Dave Page from Redmond Technology Partners, whose company was engaged by Microsoft to build the GearUp site, which is a site dedicated to providing IT professionals and business managers with timely resources and guidance through the SharePoint deployment cycle. It even includes an Internal Buzz Kit, which includes sample promotional emails, posters and PowerPoint slides - all vital pieces in the Communications Plan that all SharePoint projects should have (if you don't have one - get one. Otherwise your SharePoint project is likely to fail due to poor user adoption).
I also got to meet Dave Page from Redmond Technology Partners, whose company was engaged by Microsoft to build the GearUp site, which is a site dedicated to providing IT professionals and business managers with timely resources and guidance through the SharePoint deployment cycle. It even includes an Internal Buzz Kit, which includes sample promotional emails, posters and PowerPoint slides - all vital pieces in the Communications Plan that all SharePoint projects should have (if you don't have one - get one. Otherwise your SharePoint project is likely to fail due to poor user adoption).
Is that you Mike Fitzmaurice?
I nearly fell over tonight when I saw Mike Fitzmaurice (Microsoft Evangelist) for the first time in 12 months. He has lost about 40Kg and is shadow of the man he was before. Well done Mike!
A Possible Workaround with Content Types incorporating BDC lookups
I attended the session 'Creating Solutions with the Business Data Catalog' today at the SharePoint Conference, presented by Todd Baginski. At the end of the session, I had an idea on how to get around this limitation with Content Types (i.e. that you can add a BDC column to a Content Type). When question time came, I stood up and asked Todd whether my theory might work. He thought it was a very good idea.
So what is the idea? Well, basically it is quite a simple process to query the values in the BDC. You just need to know the the SSP name (e.g. SharedServices1), the LobSystemInstanceName (which appears in the Application Definition XML file) and the Entity that you want to query (e.g. Customers). Todd said that he will soon upload this sample code to his blog (I'm not much of a developer any more). You then take this sample code and wrap it in a custom Field Control. The User Experience will be that when you select that you want to create a field of type BDC, you select your custom type, then provide the 3 parameters required (or even a 4th to provide filtering). At runtime, the field control queries the BDC and returns the values in a drop down list. Under the covers, you could even store the associated ID of the selected BDC item. This could (potentially) be used for communicating with other BDC web parts (e.g. BDC Item web part), or could be consumed by other field controls that provide filtering capability (say to a duplicate field control that perhaps takes a 4th parameter to filter the BDC results). If you are a brave enough developer, give it a go and let me know how you go (I wouldn't mind a copy of the code).
So what is the idea? Well, basically it is quite a simple process to query the values in the BDC. You just need to know the the SSP name (e.g. SharedServices1), the LobSystemInstanceName (which appears in the Application Definition XML file) and the Entity that you want to query (e.g. Customers). Todd said that he will soon upload this sample code to his blog (I'm not much of a developer any more). You then take this sample code and wrap it in a custom Field Control. The User Experience will be that when you select that you want to create a field of type BDC, you select your custom type, then provide the 3 parameters required (or even a 4th to provide filtering). At runtime, the field control queries the BDC and returns the values in a drop down list. Under the covers, you could even store the associated ID of the selected BDC item. This could (potentially) be used for communicating with other BDC web parts (e.g. BDC Item web part), or could be consumed by other field controls that provide filtering capability (say to a duplicate field control that perhaps takes a 4th parameter to filter the BDC results). If you are a brave enough developer, give it a go and let me know how you go (I wouldn't mind a copy of the code).
Monday, March 03, 2008
I'm here at the MS SharePoint Conference in Seattle
As there wasn't going to be a SharePoint Conference in Australia this year, I decided to go this conference in Seattle, which focuses on Real-World SharePoint solutions. Apart from getting some war stories from other SharePoint Specialists, I'm looking forward to catching up with some world renowned MVP's and Arpan Shah from the Microsoft Product Team. I'm scheduled to catch up with him at the Ask the Experts Lunch on Wednesday.
Monday, November 26, 2007
Migrating InfoPath forms over to MOSS
Last week I had a customer that used InfoPath extensively for basic data capture. The forms themselves were quite basic. Most had a couple of data connections to SharePoint lists (for drop-down values), as well as the main Submit data connection. Modifying each of these forms involved migrating each of the lookup lists to the new SharePoint environment, creating the destination Forms Library to hold the submitted forms, modifying each of the data connections in InfoPath to point to these lists and libraries, and finally Publishing the form to the new location.
Of bigger concern was the fact that there were hundreds (if not thousands) of data files (i.e. .xml files containing submitted data). As you may or may not know, submitted InfoPath documents have a processing instruction at the top of the XML, which tells Windows that it is an InfoPath document, as well as where to get the InfoPath XSN template to load.
Fortunately, MOSS form libraries now have a new default view called 'Relink Documents'. By using this view, you can select each of the existing documents and relink them to the new template. Below is a screenshot:

Discovered a new issue with SharePoint 2007 stsadm Export function
Last week I had to move some team sites from an upgraded site into a new MOSS site structure. Normally when using the stsadm export function I use the following syntax, which ensures that I move across all document versions, as well as maintain document 'modified by' type information.
stsadm -o export -url http://moss_site/sites/projects/it_projects -filename it_projects.dat -includeusersecurity -versions 4
But this kept on failing for this particular site. On closer inspection of the export log I discovered that one document in the document library had 151 versions!! It was this document that was causing all of the problems.
My solution was to just move across the latest version of the document instead, which has the syntax:
stsadm -o export -url http://moss_site/sites/projects/it_projects -filename it_projects.dat -includeusersecurity -versions 2
Looking back on it now, I could have also tried to delete previous versions, but this could have been a trial and error thing (because I don't know what the export limit actually is - 50 versions? 100 versions? Who knows?)
stsadm -o export -url http://moss_site/sites/projects/it_projects -filename it_projects.dat -includeusersecurity -versions 4
But this kept on failing for this particular site. On closer inspection of the export log I discovered that one document in the document library had 151 versions!! It was this document that was causing all of the problems.
My solution was to just move across the latest version of the document instead, which has the syntax:
stsadm -o export -url http://moss_site/sites/projects/it_projects -filename it_projects.dat -includeusersecurity -versions 2
Looking back on it now, I could have also tried to delete previous versions, but this could have been a trial and error thing (because I don't know what the export limit actually is - 50 versions? 100 versions? Who knows?)
Thursday, October 25, 2007
Implications of WSS/SPS 2003 sp3
Although most of the time I am working on MOSS related projects, one of my clients still requires my support with SPS 2003. They had rebuilt the environment to be SPS sp2 on Windows Server 2003 service pack 2. If you didn't already know, this combination breaks the 'Create Site' functionality (it hangs on the Add Link to Site section). Anyway, last week I installed WSS/SPS service pack 3, which fortunately fixed this problem. However, today I discovered that the Rich Text Editor within the Content Editor Web Part no longer works. To fix this, you have to modify both ows.js and htmledit.aspx to include an additional JavaScript function called RenderActiveX. This function accepts a string, then just does a document.write(str) with it. Simple fix really, but it should have been tested more thoroughly before it was released.
Monday, August 13, 2007
Huge week at TechEd!
Well it was a massive week on the Gold Coast. The highlights for me were:
- Getting 100% on the MOSS configuration exam after only 2 hours of study at 5.30 in the morning.
- The Superman ride at Movie World
- Winning the Grand Prize!!!!
I am still not entirely sure what I have won (they are shipping it to me this week). But I did see a new Palm phone in the the basket of goodies. Apparently it is supposed to be worth $20K - I hope it is not all t-shirts and caps!
Subscribe to:
Posts (Atom)
