Feb 09

Just like the title says, if you’ve set AllowUnsafeUpdates = true, after a BreakRoleInheritance (on any SP object ie. SPWeb, SPList, SPListItem) AllowUnsafeUpdates will reset back to false.   If you need it to remain true make sure to set it back to true right after you call BreakRoleInheritance:

SPListItem li = list.Items[0];
SPContext.Current.Web.AllowUnsafeUpdates = true;
li.BreakRoleInheritance(false);
SPContext.Current.Web.AllowUnsafeUpdates = true;
li.Update();

Nov 10

This one was a mystery for a while.  If you’re running into a 403 from IE when going to a SharePoint forms auth site but you’re not getting any problems from another browser, check to see if you have Microsoft Office Live Update  installed.  I believe the latest June cumulative update will have fix shipped with it.   Here’s the KB article detaling the issue…

http://support.microsoft.com/kb/972535

Oct 12

Just spent about 2 weeks with Microsoft support on a problem related to one way trust and using the peoplepicker-searchadforests for Sharepoint.  You can find out more about the property here: http://technet.microsoft.com/en-us/library/cc263460.aspx

The problem in our situation was that we previously had set the property to be able to search the forest which in our case was called contoso.local.  SharePoint was not returning users from the trusted domain in people picker but  what was more confusing was that people picker would return users from the trusted domain who had been previously added.  So initially, we couldn’t diagnose that it wasn’t returning all users but thought it was only having a problem with a few users.  In the end, we found the problem to be that contoso.local was no longer being recognized as a forest but rather just as a domain.

Why was it being now recognized as a domain and not a forest anymore?  No clue.  If you have any ideas please chime in because that is still a mystery to me.   I’ve tripple checked and our forest is still the same name. I did notice this issue happened after the April cumulative update although I’m not sure it is related.

So our property value for peoplepicker-searchadforest had to change from:

stsadm -o setproperty -url http://contoso.com -pn peoplepicker-searchadforests -pv “forest:contoso.local“,contoso\account,*****;”domain:contoso.local”,contoso\account,****

 to the correct value:

 stsadm -o setproperty -url http://contoso.com -pn peoplepicker-searchadforests -pv “domain:contoso.local“,contoso\account,*****;”domain:contoso.local”,contoso\account,***

 It took us 2 support technicians and an escalation then finally after 2 weeks the issue was fixed with Microsoft support.  We spent a lot of time making test sites with multiple configurations but had completely missed this one detail of trying domain instead of forest.   Hope this saves someone else some time!

Sep 06

Active Directory works great with SharePoint but it’s not always the ideal solution.  ASP.NET membership works much better under certain circumstances.  Here’s a great article by Scott Guthrie about ASP.NET membership and SharePoint (http://weblogs.asp.net/scottgu/archive/2006/04/30/SharePoint-2007-_2D002D00_-Built-on-ASP.NET-2.0-.aspx).

Here’s some points I’ve come accross that may help decide when to use either solution:

When to use Active Directory

  • Users are already part of AD
  • Accounts must be centrally managed by IT
  • Accounts need to follow certain policies maintained by IT (password expiration,  password strength)
  • Users absolutely need SharePoint features only available from NTLM ie. windows explorer view for lists
  • No need for forms auth and need true Windows auth integration
  • Ideal for company intranets where the users of SharePoint are all from AD

When to use ASP.NET membership

  • For using ASP.NET login controls (http://msdn.microsoft.com/en-us/library/ms178329.aspx)  right out of the box.  Saves incredible amount of work!
  • There is a need for an account creation process, i.e. registration where the user will be granted with certain rights upon completing the registration.  
  • Need for more self service features for accounts such as “Forget Password” with a challenge and response, and a “Change Password” feature.  These come out of the box.
  • If the site is primary accesssed by users outside of the organization, AD will be convoluted with users that otherwise do not use internal resources.   Using ASP.NET membership segregates these users which also provide better protection for assets that could be accessed by internal AD users.
  • SharePoint developer/admin can support user accounts all from with the SharePoint server rather than an IT resource with rights to AD.  This is helpful where there are large bureaucracies for IT that need to be bypassed.
  • Ideal solution for partners, extranets, and public facing sites where the users do not need to be in AD. 
May 13

If you have items (pages or subsites) missing in your current navigation or quick launch links, then it maybe related to the sitemap providers DynamicChildLimit which is set by default to 50.  To change this, you’ll need to update your web.cofig as below.  Setting it to 0 will allow for no limit.

The original post I found related to this was http://www.slightlyrational.com/it/sharepoint/extending50sitelimit.

<siteMap…>
<providers>
        <add name=”GlobalNavSiteMapProvider” description=”CMS provider for Global navigation” type=”Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” NavigationType=”Global” EncodeOutput=”true” DynamicChildLimit=”0″ />
        <add name=”CombinedNavSiteMapProvider” description=”CMS provider for Combined navigation” type=”Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” NavigationType=”Combined” EncodeOutput=”true” DynamicChildLimit=”0″ />
        <add name=”CurrentNavSiteMapProvider” description=”CMS provider for Current navigation” type=”Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” NavigationType=”Current” EncodeOutput=”true” DynamicChildLimit=”0″ />
        <add name=”CurrentNavSiteMapProviderNoEncode” description=”CMS provider for Current navigation, no encoding of output” type=”Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” NavigationType=”Current” EncodeOutput=”false” DynamicChildLimit=”0″ />
</providers>
</siteMap>

May 06

I had an issue with some code that was deployed into a prod environment and threw an ‘object reference not set to an instance of an object’ error where it called the SPWeb’s AssociatedVisitorGroup.  It turned out that our production environment didn’t have its visitor group setup yet.  To do this go to the groups page  (../_layouts/groups.aspx), and on the top of of the People and Groups view click on Settings and go to Set Up Groups.  There you can create a new group or associate an already existing one. 

May 06

I had some fun times debugging this issue today.  There was an IIS virtual directory setup in the SharePoint web applications site with the same name as one of the variations in the site.  In our example, we have a variations site for japan at http://www.patrickzaw.com/jp.  There was a need to redirect a url (http://www.patrickzaw.com/jp/products) that didn’t exist within the Sharepoint site structure to another subsite that does exist (http://www.patrickzaw.com/jp/sites/productline).  The solution put in place was virtual directory created in the same web application for /jp and then under that another one for /products which was setup as a redirection to the existing subsite. 

Upon setting this up everything will work as expected until an app pool recylce, or IIS reset.  When the app pool recycles the entire site will throw an unspecified exception. 

It appears only to affect virtual directories with the same name as the variations site, but does not effect subsites with the same name. 

Our resolution was to delete the virtual directories, restart IIS, and use SharePoint redirect pages instead.  This did force us to create a subsite for /products that only had one redirect page.  Please chime in if you have some better ideas of how to implement this. 

 

Sep 05

The SmartPart Report can be downloaded at http://www.codeplex.com/SmartPartReport

If you use SmartParts then you’ll know how messy that usercontrols folder can get.  Worse, if you’ve inherited a SharePoint project with many pages that has SmartParts used all over the site, most likely you’ll need to know where each user control is being used.  This is the reason I came about making the SmartPart report.

The code is pretty straight forward.  It basically loops through each file, looks for only aspx files, and then goes through each webpart and checks to see if the type is a SmartPart. 

 You could also expand upon this and search for other web part types as well.  For example if you wanted to also look for Microsoft.SharePoint.WebPartPages.ListViewWebPart you can add it to the searchWebPartTypes array on line 83:

                    string[] searchWebPartTypes = { “SmartPart.SmartPart”, “SmartPart.AJAXSmartPart” , “Microsoft.SharePoint.WebPartPages.ListViewWebPart” };

It then uses reflection to get the “UserControl” property for a SmartPart.  Again, if you’re using this to find another web part, you could put some conditions around this and modify the propertyname to get the value you’re looking for.  Ex:

line 97:

          string propertyName = “UserControl”;
          string userControlFileName = “”;
         
          if (webPartType == “Microsoft.SharePoint.WebPartPages.ListViewWebPart”)
          {
                propertyName = “Title”;
          
}

Aug 07

public SPListItemVersion GetLatestMajorVersion(SPListItem listItem)
        {
            SPListItemVersion latestMajorSourceFileVersion = null;

            foreach (SPListItemVersion sourceListItemVersion in listItem.Versions)
            {
                Version thisVersion = new Version(sourceListItemVersion.VersionLabel);

                if (thisVersion.Minor != 0)
                {
                    continue;
                }
                else
                {
                    if (latestMajorSourceFileVersion != null)
                    {
                        Version v = new Version(latestMajorSourceFileVersion.VersionLabel);
                        if (thisVersion.Major > v.Major)
                        {
                            latestMajorSourceFileVersion = sourceListItemVersion;
                        }
                    }
                    else
                    {
                        latestMajorSourceFileVersion = sourceListItemVersion;
                    }
                }
            }

            return latestMajorSourceFileVersion;
        }

Apr 05

Sharepoint Workflow Starter is a tool I made for helping with mass starting/stopping workflows for items accross a Sharepoint site.

Download: The executable and source code are available at http://www.codeplex.com/SPWorkflowStarter.

***TEST IN YOUR DEV ENVIRONMENTS FIRST!***

The app needs to be run on a Sharepoint server with an account that has sufficient permissions to access the API.

This is what it looks like…

Overview Screenshot

So lets say you want to run the Approval workflow for every item in every list for a site and all its subsites. Here’s how we could do that:

1) Looking at the example above, you would first navigate to the site you want, in this case the root site http://stdemo.

2) Under that site we can find all the workflow templates available and we’ll select the Approval workflow template.

3) Once we select the Approval workflow template, you can check Run for all sub sites so that this workflow will run for all lists for this site and any sub sites.

4) You must choose the actions to take, stop, start, and you can also choose to use your own custom event data.

*Custom event data is the xml data passed to the workflow. When selecting a workflow template you will not see the event data that will be used by default because the workflow association to its list is what defines the event data. If you want to see what the event data looks like, select a list under that workflow template and you’ll see the event data used for that workflow association.

5) You can choose to log your results. This should always be done because I have yet to add any verbose output except in the logs.

6) Review your plan below and then click EXECUTE when ready.

The same steps above can be done for a list or single items in a list.

The tool still needs some work and if would like to help please drop me a line. Some future release features would be:

  • Running workflows for multiple items (via checkbox)
  • Better UI form design
  • Better log output control
  • Easier way to edit event data
  • A lot of code clean up :-O