My blog has moved!

My blog has moved to http://www.lamber.info. Click on the redirect button below to be redirected to the blog post.

Please update your bookmarks and use the new url for getting new updates.

Pages

Friday, April 23, 2010

SharePoint Foundation 2010 is officially available

Hi,

Stefan Goßner announced in this post that SharePoint 2010 is officially available and downloadable by this link since today.

Happy downloading

Patrick

Sunday, April 18, 2010

The Office 2010 is coming

We've Shipped!, announced the Microsoft Office 2010 Technical Beta Program Team in this post yesterday. Office 2010, SharePoint 2010, Visio 2010 and Project 2010 have reached the RTM (Release to Manufacturing) status, which is the final engineering milestone of Microsoft’s product development cycle.

Visit the http://www.the2010event.com homepage if you want to join the virtual launch of this exciting products on May 12th.

Best regards

Patrick

Saturday, April 10, 2010

You are not able to create pages or sites in Moss 2007

Hi,

when you press create page or site on SharePoint 2007 and you get a similar exception below, you probably screwed up the permissions of your master page gallery.

List does not exist

The page you selected contains a list that does not exist.  It may have been deleted by another user.   at Microsoft.SharePoint.Library.SPRequestInternalClass.GetListsWithCallback(String bstrUrl, Guid foreignWebId, String bstrListInternalName, Int32 dwBaseType, Int32 dwBaseTypeAlt, Int32 dwServerTemplate, UInt32 dwGetListFlags, UInt32 dwListFilterFlags, Boolean bPrefetchMetaData, Boolean bSecurityTrimmed, Boolean bGetSecurityData, ISP2DSafeArrayWriter p2DWriter, Int32& plRecycleBinCount)
   at Microsoft.SharePoint.Library.SPRequest.GetListsWithCallback(String bstrUrl, Guid foreignWebId, String bstrListInternalName, Int32 dwBaseType, Int32 dwBaseTypeAlt, Int32 dwServerTemplate, UInt32 dwGetListFlags, UInt32 dwListFilterFlags, Boolean bPrefetchMetaData, Boolean bSecurityTrimmed, Boolean bGetSecurityData, ISP2DSafeArrayWriter p2DWriter, Int32& plRecycleBinCount)
Troubleshoot issues with Windows SharePoint Services.

Go to the master page gallery and modify the permissions (probably some permissions of your groups or users where removed) and add the necessary groups or users to your master page gallery.

Best regards

patrick

Saturday, April 3, 2010

Why the Moss crawler might not working?

This week I had to fight against our indexing and querying server in our new SharePoint farm. It is a farm environment consisting of several web-front ends and this poor little guy :). At the beginning, as usual, everything seemed to work as expected and we started to create our first content sources for indexing. You know what… my long and apparently endless journey begun exactly at this moment:

The crawler could not communicate with the server. Check that the server is available and that the firewall access is configured

At the beginning this error was misleading. I double-checked the firewall settings and found no issues. The machines are communicating with each other without issues. Now you might be thinking… what else?

Before I start to tell you how I solved this and another issue, I would like to give you an advice:

Advice: before banging your head against the wall or trying to kill some developers near you, do following:

1) use RDC to connect on your indexing and crawling server

2) open a browser and try to open the SharePoint site you want to crawl by using the credentials of your search account

Most of the issues will popup during this moment:

1) You see if the search account has not enough rights to access your page

2) You see if there are missing assemblies or errors in the web.config

Only because your site is working on your web-front ends, this does not mean that it works on your indexing and querying machine. If some of the above cases occur, probably, you know what are your next steps.

In my case it was a custom WebPart developed in our team. The WebPart was working like a charm when it was not crawled. When the pages were crawled, an exception was caught causing the misleading error message you saw before. Probably, you are using some kind of customizations that are breaking the indexer. Try to remove them from your site for testing purposes or debug the code with Visual Studio.  

Still here? Damn… . After the correction of the bug I was also thinking that everything should work. But I was wrong. And voila’, the next error occurred:

Error in the site data web service

Interestingly, the improved WebPart was not throwing the exception and the pages worked when browsed on the indexing server. After hours of research I finally found the solution for my problem. It was again a customization of our development team. It is a HTTPModule that is responsible for the URL rewriting of our SharePoint pages. The indexer seemed to hate our redirections with the Response.Redirect command. I simply removed the automatic redirection on the indexing server. Afterwards, everything worked fine.

Naturally, this special case occurred only because of our custom code. But I think that we can learn from it anyway. If some of the errors above are occurring, you probably forgot to update some code or you are missing some dlls on your indexing server. So try to debug and test your pages on the server to see what your issue might be.

Hope this helps. Happy eastern

Patrick

Friday, April 2, 2010

How to programmatically change the page template in Moss 2007

Hello to everyone,

in our team we are using the WCM features for Moss 2007 for some customers. It’s a common practice to backup the production environments up to a certain degree and restore them into our development environments. Until now, this approach worked well until we noticed an interesting exception when we tried to change the page properties of a publishing page:

8e2s    Medium      Unknown SPRequest error occurred. More information: 0x80070057 03/24/2010 08:09:26.88     w3wp.exe (0x3AA8)  0x27AC CMS  Publishing  6wyd    Medium      GetFileFromUrl: ArgumentException when attempting get file Url http://productionServerUrl/_catalogs/masterpage/pageTemplateUrl.aspx Value does not fall within the expected range.

Moss 2007 is not able to open the resource located on that URL. This is clear, we are working on our development environment and Moss tries to access a resource from the productive environment. How should it be possible to get a resource that is not reachable? :) The absolute path stored in the page layouts property ensures that we get one of these beautiful yellow pages that probably every developers encountered once in a SharePoint life.

My basic idea was to solve this issue by changing the page layout reference that is defined in our site collection. Instead of using the absolute path it would be better to store as page layout the relative path. In this way we ensure that the reference also works in our development environment.

My first approach was to try to modify this property directly in the publishing object model of Moss 2007. So I simply tried to reassign the page layout on the development environment. Unfortunately, without success. When you try to access the PageLayout property of the publishing page, you will get exactly the exception you saw before.

Therefore, I changed the approach and went to the more general object model. I used the SPItem class and the Field properties of this class to modify the page layouts settings. The layout settings are stored into a property called “PublishingPageLayout” in your list item. The information is stored in comma-delimited format:

- Address of the Resource, Title of the Resource

The code snipped below uses a publishing page (the variable page):

1.  String[] pageLayouts = page.ListItem.Properties  ["PublishingPageLayout"].ToString().Split(',');

2. if (Uri.IsWellFormedUriString(pageLayouts[0], UriKind.Absolute))
3. {
4.    String newPageLayout = Regex.Replace(page.ListItem.Properties["PublishingPageLayout"].ToString(), @"^([a-zA-Z]+:\/\/)?([^\/]*)", String.Empty);

5.    page.CheckOut(); 
6.    page.ListItem.Properties["PublishingPageLayout"] = newPageLayout;

7.    page.ListItem.Update();
8.    page.CheckIn("Publishing PageLayout correction");

9.    if (page.ListItem.ParentList.EnableModeration)
10.  {
11.      page.ListItem.File.Approve("Publishing PageLayout correction");
12.   }

13. }

At line 1-2 we check if we really have an absolute page layout. If this is true, remove with the regular expression the domain name. In this case we are getting the relative path to the resource (please read the warning afterwards). Then the code checks-out the page and assigns the new value to the "PublishingPageLayout” property (line 5 and 6). After an update and a check-in, we get in business.

Warning: this piece of code was only tested with a site collection residing directly in the host. For solutions like http://host/siteCollectionName this solution has to be adapted.

After running this code it was possible for me to change the wrong page layouts address with a relative one. After this change, the development environment worked as expected and the exception above vanished.

Hope this helps,

Patrick

Thursday, April 1, 2010

MOSS 2007: access a choice field via object model or filter it using CAML queries

Hi,

sometimes you are coming across to some personalization where you need to directly access, modify or filter some kind of SharePoint lists. Today, I’m going to speak in which way you can access a choice field of a SharePoint list. The first example shows how to access the different attributes of a choice field via code. The second example shows how you might filter the list items depending of their stored choice field values.

First of all, let’s say for the shake of simplicity that we have a personalized list of contacts with a custom field called “ContactType”. This field is a choice field containing three different options: “Friends”, “Business”, and “Other”. Finally, imagine we created some test data in that list.

How do I access the different choices of a choice group?

Now, we want to know which choices are available in the choice field. We can do it programmatically by referencing the field and casting it into a SharePoint object model class. This class encapsulates the attributes of the choice field and simplifies the access on them. The next example shows how we retrieve the choice field “ContactType” and how we are able to loop the different choices a user might have in the list. The code snipped is shown below:

1.  String webUrl = “putYourUrlHere”;

2.  String listName = “putYourListNameHere”;

4. using (SPSite site = new SPSite(webUrl)) {

5.   using (SPWeb web = site.OpenWeb()) {

6.      SPList list = web.Lists[listName];

7.      SPFieldChoice field = (SPFieldChoice)list.Fields[“ContactType”];

8.      foreach (String item in field.Choices) {

9.        // do whatever you need to do here

10.     }

11.  }

12.}

The code is straightforward. We are only accessing the SPWeb and SPList that we want to retrieve. Afterwards, we access the field of the list called “ContactType” and cast it into a SPFieldChoice. From now on, we are able to process the field without any issues and simply by calling the instantiated object.

How do I filter values directly from the list?

Image we want to retrieve from our list the contacts of a certain contact type. Let’s say we want to retrieve all friends stored in the list. That means that we want to get all list items with the “ContactType” = “Friend”. Naturally, you can get all list items and loop over all. However, this certainly does not speed up your code :). Because of that, we are going to use a CAML query to retrieve only the desired records from the database. I would like to recommend you using CAML Builder of U2U. This tool simplifies your life building CAML queries dramatically.

Hint: when you are creating a query with the U2U CAML Builder, it generates for you the CAML syntax encapsulated into a query tag. If you want to use these queries in your code, remove the query tags from the query. if you don’t do it, you might encounter an exception. You can see that I don’t use the enclosing query tags in my example below .

The next code snipped does nothing special. We are only retrieving the list and web. Afterwards, we execute the query in this list using a SPQuery instance. This instance needs the CAML query that should be executed.

1.  String webUrl = “putYourUrlHere”;

2.  String listName = “putYourListNameHere”;

3.  String filteringValue = “Friend”;

4.  SPQuery filterQuery = new SPQuery();

5.  // generate the query and put the filtering value

6.  // please note that the “FieldRef” in my case is ‘ContactType’.

7.  // you have to ensure that you are using the right field reference.

8.  query.Query = @"<Where><Contains><FieldRef                      9.  Name='ContactType' /><Value                                                10. Type='Choice'>Friend</Value></Contains></Where>";

11. // open the site and get the corresponding web instance

12. using (SPSite site = new SPSite(webUrl)) {

13.   using (SPWeb web = site.OpenWeb()) {

14.      SPList list = web.Lists[listName];

15.      SPListItemCollection result= list.Get(query);

16.      // do whatever you need to do with your filtered results

17.    }

18. }

The most important lines of code are between 8 and 10. You see I’m using the CAML query and filter all the fields containing ContactType (=> fieldRef=’ContactType’) with the values of type ‘Choice’ having the value “Friend”.

Naturally, I left for simplicity all exception handling.

Hope this helps

Patrick