Category Archives: Uncategorized

Upgrading Masterpage and UIVersion from SharePoint 2007 to SharePoint 2010 without v4.master

When upgrading from SharePoint 2007 to SharePoint 2010, several scenarios are possible. When using the database attach method, it’s possible to stay in “V3” mode, or execute a visual upgrade too and make use of all SharePoint 2010 love. Whenever custom masterpages have been created for SharePoint 2007, the visual upgrade itself isn’t too much of an option: it upgrades the UIVersion of the current web to V4, but the custom masterpage is replaced by the default v4.master, which (of course) doesn’t provide any customizations. the next step is to create a new customized masterpage for SharePoint 2010, add it to your site and make sure to set this masterpage as the new default/custom masterpage.

The scenario I wanted to achieve, was the following:

  1. Deploy my custom solutions with all masterpages already upgraded to SP2010, so only the UIVersion should be upgraded
  2. Attach the content database
  3. Upgrade the site to v4 mode, without the need of a v4.master deployment

The problems of (visual) upgrading to SharePoint 2010

The problems of visual upgrading consist of several issues: it doesn’t work right out of the box (but that is expected), and some steps are needed to deploy and undeploy a masterpage, before the real SP2010 masterpage can be set, because the v4.master seems to be required

1 – Upgrade the site doesn’t work immediately

As stated above, a visual upgrade using the user interface or upgrade by code/powershell is needed to let the existing site run in v4 mode:

1: $web = Get-SPWeb http://site
2: $web.UIVersion = 4
3: $web.Update()

sadly, this will bug out, because SharePoint requires the v4.master to be able to upgrade to v4-mode. The v4.master has to be made available via a feature (or manually) in the masterpage gallery, before the upgrade can be executed.

2 – Upgrade to a masterpage that isn’t needed

Assuming that all customizations that did exist in SharePoint 2007 need to be retained, the above solution isn’t the final solution. Next steps are to create a SharePoint 2010 masterpage with the customizations, deploy that masterpage, and set that masterpage as the default/custom masterpage for that site. And because that v4.master wasn’t needed at all, that feature should be deactivated, or even better for hygienic reasons, be uninstalled and deleted.

why is this a problem?

As this isn’t to much of a hassle for a few sites, it does whenever some big portals/intranets are migrated, with a lot of different masterpages. When working with about 10.000 webs, this needs to be automated, but activating anddeactivating 10000 times a feature can be quite time consuming. A lot of time can be saved, whenever the customized masterpages are already “SP2010-ready”, so all is left to do, is to set the UIVersion to 4.

The solution of quickly applying a visual upgrade without a v4.master

As described above. I wanted to achieve the following scenario:

  1. Deploy my custom solutions with all masterpages already upgraded to SP2010, so only the UIVersion should be upgraded
  2. Attach the content database
  3. Upgrade the site.

what happens behind the scenes?

When firing up reflector, we see that the following happens in code:

When the UIVersion is set, an internal function called “SetUIVersion” is executed. This function takes the UIVersion as a parameter and a boolean which decides wether or not to set the masterpage. Unfortunately, this function is an internal function, so it can’t be used without using reflection.

The SetUIVersion function contains some logic to determine whether to rollback to UIVersion 3, or to upgrade to UIVersion 4. After the decision, the internal function SwitchMasterPages is called, with 5 parameters:

That function is called with the following parameters

And what happens in this function gets interesting. This function checks what default and custom masterpage are currently set (the V3 masterpages), and stores them in the propertybag of the current web, specified, by the parameters specified in the function. To determine what new masterpage needs to be set, that same propertybag is checked: in this case the properties “v4master” and “v4customMaster”. if they are empty, the default v4.master is used:

and in this part of the function, the error is thrown that the default masterpage couldn’t be found:

When the propertybag isn’t empty, the value of that propertybag is set as masterpage:

And that is our solution!

Simply set add the v4master and v4customMaster to the SPWeb propertybag, with the values of the current masterpage. Update the UIVersion of the web and update it. That should do the trick:

Summary

Upgrading a SP2007 site to SP2010 is easy to do, but it can consume quite some time and operations. To streamline the upgrade process of a SP2007 site to SP2010, it’s easier to upgrade the Sp2007 masterpages beforehand and include them, with the same name, in the solution. Deploy the solutions, attach the databases and upgrade every SPWeb using the above powershell. That should do the trick!

GeoSearch with Fast Search for SharePoint 2010 – Part 1

This is the first part of a series of blogposts about GeoSearch with Fast Search for SharePoint. I recently held some presentations about extending the power of Fast (on DIWUG and the Dutch TechDays 2012) and one of the subjects that I talked about was on how to search for locations, sort on distances etcetera. The recording of my sessions will be made available on Channel 9.

Why using Fast search for SharePoint 2010 for this purpose?

It’s possible to compute distances between locations in a lot different ways. For example, address can be queried against SQL Server (if the correct data is available), or those addresses can be used in conjunction with the Bing Geocode services. A custom webpart with logic to query one of those services with the users/objects current location and all list items with location information takes little time, but performance issues can pop up in no time. how is the performance when there are 200 items in a list? and 2000? 20000? maybe 200000? Surely, I can imagine that there are some smart solutions to send 200000 locations to the geocode service and receive them back, but remember: how did you extract that information from a sharepoint list? That takes quite some time. It is even getting harder when data comes from several lists, not even thought about data from several site collections, external data (BCS is an option here btw) or, location information that resides insidedocument.

Continue reading

Upgrading sandbox solutions to full trust solutions

This blogpost describes the problems that could have come up when upgrading sandbox solutions to fulltrust solutions and how i Tested it. Read the conclusion in the end for the pitfalls that have to be taken care of.

At the insurance company that I work, Achmea, one the responsibilities that I have include the SP2010 guidelines. One of those guidelines is:

  • use Sandbox solutions.

of course this is a guideline, which has some “unless”  clauses, because the possibilities for custom solutions would be very smart then.

Continue reading

Fast Search for SharePoint caveat: Apply a sortformula

Fast Search for SharePoint provides four great possibilities to influence the sort order of your resultset that was returned:

  • Sort by Managed property
  • Sort by Rank
  • Sort by Formula
  • Sort in Random order

When I was working on my presentaion and demo for the diwug (Dutch Information Worker User Group) last week, to show off on how you can improve your search experience by using custom ranking models, custom sort orders and extending the pipeline, I ran into an issue that I wasn’t aware off. When I used a custom sort formula, I did get the right result set, but not the right result order.

Continue reading

Fast Search for SharePoint gotcha – query suggestions

At the company i work for, we do have around 30(?!) different labels and we decided that all websites of those labels, should be hosted on one platform: SharePoint 2010. This consolidation to one platform should really decrease costs, because we now have one generic way of developing, one platform to take care of and we can reuse a lot of components.  One of the service applications that we wanted to reuse amongst all applications, is the Fast Query Service Application, as we have a Fast instance running.  Our labels are really enthousiast about the Fast Search for SharePoint capabilities due to fact that a lot of interesting features, like visual best bets, can be configured from within the UI. Other things, like new ranking models can easily be configured via powershell. There is just one index, with all public information in it: personal details or things like that, will not be indexed! By configuring scopes in a correct way, we can prevent information from label 1 to appear in the search results on label 2. If, for some reason, those results appeared by accident (wrongly configured scope), that wouldn’t be too much of a problem, as that can be fixed real soon.

Continue reading

Feature stapling used to execute code onSiteCreation

Some time ago I wanted to enable some features upon a siteCollection creation, but I couldnt find an eventhandler which allowed me to execute those actions. You could, of course, add or alter the ONET.XML for a new Template, but if you need to run code/activate features on Site Creation for multiple definitions, this can be a hell of a job. One of the possiblities that comes in is calles FeatureStapling. This is a technique used to activate features to siteDefinitions and it works as follows:

It’s a feature with a farm-wide scope, which is needed to be able to be activated when a site is created. This could be the content of the stapling.xml

    1 <Elements xmlns=”http://schemas.microsoft.com/sharepoint/”>

    2   <FeatureSiteTemplateAssociation Id=”F6924D36-2FA8-4f0b-B16D-06B7250180FA” TemplateName=”GLOBAL” />

    3   <FeatureSiteTemplateAssociation Id=”F6924D36-2FA8-4f0b-B16D-06B7250180FA” TemplateName=”STS#1″ />

    4 </Elements>

as seen, it contains a FeatureSiteTemplateAssociation tag with and ID that references to a feature that needs to be activated for a site. In addition to that, a TemplateName is provided with the templateName of the SiteDefinition that the feature needs to be activated to. This way you can activate features on site creation. When code is put in the OnFeatureActicatedEvent of the feature that is referenced to, you can run code when the site is created!

NOTE: When a SiteDefinition has it’s setting “AllowGlobalFeatureAssociations” set to FALSE, the featureStaple won’t work. Check for example the STS#1 definition (Blank page)
(location: %12HIVE%\TEMPLATE\1033\XML\WEBTEMP.XML)

Using the CrossListQueryInfo and CrossListQueryCache

Lately, I am relatively a lot working with the CrossListQueryInfo. This is a way to query multiple lists at once, crossing multiple SPWebs, if you want to. And, the main reason why I used it, it’s possible to use the cached lists of the sitecollection, to improve performance! The first steps with this CrossListQueryInfo can be quite frustrating, as there isnt too much documentation to find on.

I will start with a code sample, to show how to use this to query multuple webs to retrieve Items with the contentType News Item OR Location News Item from the publishing pages. When you are going to the CrossListQueryInfo, it´s smart to make use of U2U´s Caml Query Builder, to quickly build up thecaml that you want use.
Things to keep in mind while using the CrossListQueryInfo:

  • The results that are returned are ONLY PUBLISHED items. I was breaking my head around this one, because I was sure that my query was good, the CAML Query builder also returned a result, but theCrossListQueryCache didn’t. After publishing, all the results showed up properly
  • ViewFields: Insert the fields that you want to see. If there is a field inside that doesnt exist in the list that you query, your result will be nill, nada, nothing. Make sure that you put in the INTERNAL field names!
  • RowLimit: When filling in value ‘0’, you won’t see any results
  • When using the CrossListQueryCache , make sure not to use the GetSiteData that uses the SPWeb param: GetSiteData(SPWeb web) and GetSiteData(SPWeb web, SPSiteDataQuery query) DO NOT use caching!!
  • and make sure to use Microsoft.SharePoint.WebPartPages.WebPart! This WebPart inherits from System.Web.UI.WebControls.WebParts.WebPart and enhances it with some extra functionality for connected webparts, client-side programming and data caching!! Thanks to Waldek Mastykarz for sharing this info.

Below is an example of a query that queries all the Publishing pages libraries that resides in the current SPWeb and all childWebs.

 

private DataTable ExampleQuery()

        {

            clqi = new CrossListQueryInfo();

 

            // Insert the list types that you want to use. In this case, its the publishing page library (850, see code below)

            clqi.Lists = "<Lists ServerTemplate=\"" + (int)ListServerTemplateCodes.PageLibrary + "\" />";

 

            // Insert the fields that you want to see. If there is a field inside that doesnt exist in the list that you query, your result will be nill, nada, nothing.

            // Make sure that you put in the INTERNAL field names!

            clqi.ViewFields = "<FieldRef Name=\"Title\" /><FieldRef Name=\"FileLeafRef\" /><FieldRef Name=\"Nieuws_x0020_Type\" /><FieldRef Name=\"Nieuws_x0020_Leverancier\" /><FieldRef Name=\"Uitgelicht\" /><FieldRef Name=\"Created\" /><FieldRef Name=\"Comments\" />";

 

            // scop to use. Another possibility is SiteCollection

            clqi.Webs = "<Webs Scope=\"Recursive\" />";

 

            // turn the cache on

            clqi.UseCache = true;

 

            // if row limit == 0, you will get 0 results

            clqi.RowLimit = 100;

 

            // I know a stringbuilder would be better, but i wanted to show the markup of the query

            clqi.Query = "<OrderBy>" +

                            "<FieldRef Name='Title' />" +

                        "</OrderBy>" +

                        "<Where>" +

                            "<Or>" +

                                "<Eq>" +

                                    "<FieldRef Name='ContentType' />" +

                                    "<Value Type='Text'>News Item</Value>" +

                                "</Eq>" +

                                "<Eq>" +

                                    "<FieldRef Name='ContentType' />" +

                                    "<Value Type='Text'>LocationNews Item</Value>" +

                                "</Eq>" +

                            "</Or>" +

                        "</Where>";

 

            // put the CrossListQueryInfo object into the CrossListQueryCache

            CrossListQueryCache clqc = new CrossListQueryCache(clqi);

 

            // and query the data!

            // make sure: the GetSiteData(SPWeb web) and GetSiteData(SPWeb web, SPSiteDataQuery query) DO NOT use caching!!!

            DataTable tbl = clqc.GetSiteData((SPContext.Current.Site, CrossListQueryCache.ContextUrl());

 

            // return the datatable

            return tbl;

        }

The enum below can be used to make life a little bit easier. I got it from:http://www.aspenhorizons.com/devblog/?p=29

public enum ListServerTemplateCodes
    {

        GenericList = 100,

        DocumentLibrary = 101,

        Survey = 102,

        LinksList = 103,

        AnnouncementsList = 104,

        ContactsList = 105,

        EventsList = 106,

        TasksList = 107,

        DiscussionBoard = 108,

        PictureLibrary = 109,

        DataSources = 110,

        SiteTemplateGallery = 111,

        UserInformationList = 112,

        WebPartGallery = 113,

        ListTemplateGallery = 114,

        XMLFormLibrary = 115,

        MasterPagesGallery = 116,

        NoCodeWorkflows = 117,

        CustomWorkflowProcess = 118,

        WikiPageLibrary = 119,

        CustomGridForAList = 120,

        DataConnectionLibrary = 130,

        WorkflowHistory = 140,

        GanttTasksList = 150,

        MeetingSeriesList = 200,

        MeetingAgendaList = 201,

        MeetingAttendeesList = 202,

        MeetingDecisionsList = 204,

        MeetingObjectivesList = 207,

        MeetingTextBox = 210,

        MeetingThingsToBringList = 211,

        MeetingWorkspacePagesList = 212,

        PortalSitesList = 300,

        BlogPostsList = 301,

        BlogCommentsList = 302,

        BlogCategoriesList = 303,

        PageLibrary = 850,

        IssueTracking = 1100,

        AdministratorTasksList = 1200,

        PersonalDocumentLibrary = 2002,

        PrivateDocumentLibrary = 2003

    }

more information about this subject can be found at:

http://sharepoint.nailhead.net/2008/04/musing-on-crosslistquerycache-class.html

SharePoint Logging to the ULS and the eventlogs

Tis weekend I came across a function that makes it easy to log to the ULS, Diagnostic Logging. I even didnt know about the namespaces where the classes reside in.

The first one is a class that can log to the ULS, Diagnostic logging: Microsoft.Office.Server.Diagnostics

when using

PortalLog.LogString(“Exception Occurred: {0} || {1}”, ex.Message, ex.StackTrace);

it’s possible to write tot the diagnostic logging. It contains several other functions like a DebugLogString, and

PortalLog.LaunchWatson(ex);

to launch Dr. Watson

When you want to write to the eventlog, use the following namespace and code: Microsoft.SharePoint.Portal.Diagnostics

SafeEventLog l = new SafeEventLog();

l.WriteEntry(ex, EventLogEntryType.Error);