Wednesday 7 December 2011

Show Attribute Values in XSL

Nice snippet for people who are creating xslt sheets in SharePoint:

<xsl:for-each select="./@*">
<xsl:value-of select="name()"></xsl:value-of>

<xsl:value-of select="."></xsl:value-of>

</xsl:for-each>

Thursday 3 November 2011

Farm administrator can't add new web application or extend/delete an existing one

Case
I was working on a fresh VM installation, installing and configuring my SharePoint Environment. Unfortunately I stumbled on the problem not being able to remove the default
Web Application or creating a new one.


Problem
I started checking if all my permissions where sufficient. I checked Farm Administrators, WPG roles, Config Wizard, SQL Permissions, but it didn’t make any difference.


Solution
As a last resort I starting checking my client settings. It didn’t make sense how, but this was where the solution was hiding.


I assumed that, because some functions worked and some didn’t, that the page worked as expected. There were no script errors or messages from IE 9 that things didn’t work proper. Apparently execution or loading some active x or script was being blocked, because the page worked fine after applying some changed settings and restarting IE:



I noticed that the Uri of the Web application was a ‘trusted sites’, thought
it was running on my local machine. I added the Uri to the correct internet
security policy. Just go to internet options, click security tab, remove the Uri
from 'trusted sites' and add it to 'local intranet'.

Monday 8 August 2011

Deploying Site Templates in the Solution Gallery

Case
I downloaded a couple of site templates from the Solution Gallary of my SharePoint Portal.

I want to put these site templates in a Solution Package so I can easily deploy them in my development enviroments.

I just want to deploy the solution, go to my site collection and greate the subpages I need.

Problem
After putting the file in the correct location (_catalogs/solutions) in my site collection, I noticed I couldn't activate the templates. Activating the templates is necessary to be able to select the template while creating a new site.

Solution
The following solution turned out to work for me:

- Create a new Module in VS2010.
- Add the site templates to your Module.


[Module Name="Templates" List="121" Url="_catalogs/solutions"]
[File Path="Templates\Template_Name.wsp" Url="Template_Name.wsp" Type="GhostableInLibrary"]
[Property Name="ContentType" Value="Solution Gallery" /]
[Property Name="SolutionTitle" Value="Template Name" /]
[Property Name="SolutionDescription" Value="Standard Template" /]
[/File]
[/Module]


* Replace [ and ] signs with less than (<) and greater than (>) signs.


- Add an eventreceiver to the feature and uncomment 'FeatureActivated'


SPSite currentSite = (SPSite)properties.Feature.Parent;

// Get all names of added solutions
List solutionName = new List();
SPUserSolutionCollection solutionsCollection = currentSite.Solutions;

foreach (SPUserSolution solution in currentSite.Solutions)
{
string name = solution.Name;
if (!solutionName.Contains(name))
{
solutionName.Add(name);
}
}

// Add new solutions to the collection of the gallery
SPDocumentLibrary solutionsGallery = (SPDocumentLibrary)currentSite.GetCatalog(SPListTemplateType.SolutionCatalog);
foreach (SPListItem item in solutionsGallery.Items)
{
if (!solutionName.Contains(item.Name))
{
solutionsCollection.Add(item.ID);
}
}

// Properly activate solutions
SPFeatureCollection featureCollection = currentSite.Features;
foreach (SPUserSolution solution in solutionsCollection)
{
Guid solutionId = solution.SolutionId;

SPFeatureDefinitionCollection siteFeatures = currentSite.FeatureDefinitions;

var features = from SPFeatureDefinition f in siteFeatures
where f.SolutionId.Equals(solutionId) && f.Scope == SPFeatureScope.Site
select f;

foreach (SPFeatureDefinition featureDefinition in features)
{
SPFeature foundFeature = featureCollection[featureDefinition.Id];

if (foundFeature == null)
currentSite.Features.Add(featureDefinition.Id, false, SPFeatureDefinitionScope.Site);
}
}

Friday 8 July 2011

Redirecting userdisp.aspx to custom User Profile Page

Case
Because we are building a custom User Profile Page to display custom properties, we wanted to redirect the /_layouts/userdisp.aspx request to our custom LayoutsPage. This request is the default request of SharePoint to the built-in Profile Page.

Problem
The /_layouts/groups.aspx displays all groups in a collection. When you click on the groupname to display all members, it sends you to the /_layouts/userdisp.aspx which will redirect you to the correct /_layouts/people.aspx?MembershipGroupId.

Our /_layouts/userdisp.aspx should do the same, but how does SharePoint determine when it needs to show a group or user?

Solution
The solution could be found in the Microsoft.SharePoint.ApplicationPages.dll and original userdisp.aspx file.

In your SharePoint solution create a new application page. Make sure it's mapped to the /_layouts/ folder.

In your .aspx file
Add this control to the ContentPlaceHolder 'PlaceHolderMain':

[SharePoint:FormComponent id="UserListForm" TemplateName="UserListForm" ControlMode="Display" runat="server"/] (replace [ to make it a tag ;-)

In your .cs file
Add the following code to Page_Load:

int result = 0;
string url = "User/UserProfile.aspx?" + base.Request.QueryString.ToString();

if (base.Request.QueryString["ID"] != null)
{
if (!int.TryParse(base.Request.QueryString["ID"], out result) || (result <= 0))
{
throw new SPException(SPResource.GetString("InvalidQueryString", new object[] { "ID" }));
}
}
else
{
result = base.Web.CurrentUser.ID;

if (result <= 0)
{
throw new SPException(SPResource.GetString("InvalidQueryString", new object[] { "ID" }));
}

this.UserListForm.ItemId = result;
}

this.UserListForm.ListId = base.Web.SiteUserInfoList.ID;

SPListItem listItem = this.UserListForm.ListItem;
SPContentTypeId id = (SPContentTypeId)listItem["ContentTypeId"];

if (SPBuiltInContentTypeId.SharePointGroup.IsParentOf(id))
{
url = "people.aspx?MembershipGroupId=" + listItem.ID.ToString(CultureInfo.InvariantCulture);
string keyOrValueToEncode = base.Request.QueryString["Source"];

if (keyOrValueToEncode != null)
{
url = url + "&Source=" + SPHttpUtility.UrlKeyValueEncode(keyOrValueToEncode);
}
}

SPUtility.Redirect(url, SPRedirectFlags.RelativeToLayoutsPage, this.Context);

}

This should do the trick!

Wednesday 2 February 2011

List Error when picking SiteTemplate - 0x81020012

Case
We were creating a new site definition for a customer build up with elements of the new SharePoint 2010 Features in Visual Studio 2010. At some point the solution started trowing errors when choosing the Site Template with the template picker:



A list, survey, discussion board, or document library with the specified title
already exists in this Web site. Please choose another title. 0x81020012


Problem
After analyzing the problem we discovered that VS2010 what deploying the Template Files to ‘14-hive \ Template \ Solution’ instead of ‘14-hive \ Template \ SiteTemplates \ Solution \ xml’. This way, since the webtemp_*.xml was deployed correctly, it was possible to choose the template in the template picker. When selected, SharePoint couldn’t find the onet.xml-file.

If this onet.xml-file is missing SharePoint throws this fuzzy ‘list, survey, discussion board, or document library with the specified title already exists’ message. You can test this by throwing away the file from your ‘14-hive \ Template \ SiteTemplates \ Solution \ xml’-directory.

What went wrong?
By default VS2010 knows the onet.xml-file should be located in the ‘14-hive \ Template \ SiteTemplates \ Solution \xml’-directory. Every file you add will be configured to be deployed in this path.

But when you include a new file, in this case my onet.xml, VS2010 sets the path to ‘{SharePointRoot} \ Template \ Solution \ SiteDefinition ’.

Solution
Go back to VS2010 and check the following settings in your site definition:

Onet.xml

  • Deployment Location:
    {SharePointRoot}\Template\SiteTemplates\Csolutions.SharePoint.SalesPortal.Site\Xml\
  • Deployment Type: TemplateFile

Webtemp_*.xml

  • Deployment Location:
    {SharePointRoot}\Template\SiteTemplates\Csolutions.SharePoint.SalesPortal.Site\Xml\
  • Deployment Type: TemplateFile

Re-deploy the solution and recreate the sitecollection with the correct template. This solved the problem for me.

Friday 28 January 2011

Microsoft.SharePoint.ApplicationPages

So you want to create a silk-layed-out SharePoint Administration page? Then you need to reference the Microsoft.SharePoint.ApplicationPages.dll!

Problem
I was looking for the Microsoft.SharePoint.ApplicationPages assembly, but I couldn't reference it from the assembly cache. Apparently it isn't begin installed in the assembly bin, but in the _app_bin of your web application.

Solution
You can create a (web app undependent) reference to the dll from the following location:
SharePoint 2007: 12-hive\CONFIG\BIN
SharePoint 2010: 14-hive\CONFIG\BIN

Monday 24 January 2011

Programmatically Set Master Page of Publishing Sites

Case
SharePoint Standard has a nice feature that allows configurating the Master Page on a Site Collection Level. This feature presents itself when you enabled the ‘SharePoint Server Publishing Infrastructure’-feature, found in the Site Collection Features.

Now you can use the ‘Site Master Page Settings’ (/_Layouts/ChangeSiteMasterPage.aspx) to set the Site Master Page and System Master Page.

Problem
But what does a Site and System Master Page mean? And how do you set these properties programmatically?


Solution

Site Master Page
This is the master page that is being used by publishing pages. This means that you use an other masterpage for views, etc.

System Master Page
This is the master page that is being used by system pages like settings.aspx, Forms and view pages like the view of document library pages.

The code
[Guid("00000000-0000-0000-0000-000000000000")] // Add Guid here
public class
StylingEventReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
if (properties != null
&& properties.Feature != null
&& properties.Feature.Parent != null
&& properties.Feature.Parent.GetType() == typeof(SPSite))
{
SPSite site = (SPSite)properties.Feature.Parent;

using (SPWeb rootWeb = site.RootWeb)
{
rootWeb.AllowUnsafeUpdates = true;
rootWeb.MasterUrl = "/_catalogs/masterpage/v4.customer.master";
rootWeb.CustomMasterUrl = "/_catalogs/masterpage/V4.customer.master";
rootWeb.Update();
rootWeb.AllowUnsafeUpdates = false;
}
}
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
if (properties != null
&& properties.Feature != null
&& properties.Feature.Parent != null
&& properties.Feature.Parent.GetType() == typeof(SPSite))
{
SPSite site = (SPSite)properties.Feature.Parent;

using (SPWeb rootWeb = site.RootWeb)
{
rootWeb.AllowUnsafeUpdates = true;
rootWeb.MasterUrl = "/_catalogs/masterpage/v4.master";
rootWeb.CustomMasterUrl = "/_catalogs/masterpage/v4.master";
rootWeb.Update();
rootWeb.AllowUnsafeUpdates = false;
}
}
}
}

Thursday 10 June 2010

Explorer and test Webservices

Case

I needed to explorer and test a corporate webservice. I needed to know which functionalities the webservice delivers, what kind of parameters the webservice expected and with what kind of responses the webservice replies.

Problem

The webservice wasn't documented and before a wanted to try to make a custom application I looked for a more dynamic solution. I didn't have the time to write a good testing program...

Solution

I learned that the awnser was pretty easy. Just use this handy tool: http://www.codeplex.com/WebserviceStudio

It allows you to explorer webservices easily!

Tuesday 11 May 2010

Converting Reporting Services (SSRS) rdl from 2005 into 2000

Case
I receive a error when uploading my report.

Error number: 0x80048298

Information:
[CrmException: Exception of
type Microsoft.Crm.CrmException was thrown.]
Microsoft.Crm.Application.Platform.Report. InternalCreate(String xml) +721
Microsoft.Crm.Application.Platform.Entity.Create() +109
Microsoft.Crm.Application.Forms.AppForm. RaiseDataEvent(FormEventId eventId)
+408 Microsoft.Crm.Application.Forms.EndUserForm. Initialize(Entity entity) +57
Microsoft.Crm.Application.Forms.EndUserForm. Execute(Entity entity) +13
Microsoft.Crm.Web.Tools.ReportProperty. ReportPropertyPage.ConfigureForm() +202
Microsoft.Crm.Application.Controls.AppPage. OnPreRender(EventArgs e) +30
System.Web.UI.Control.PreRenderRecursiveInternal() +62
System.Web.UI.Page.ProcessRequestMain() +1499
Problem
I made a mistake and created a report in VS2005 instead of VS2003. How could I change this?

Gary Cowan gave a real good tip on : http://sqlservertipsandtricks.blogspot.com/2008/06/converting-reporting-services-ssrs-rdl.html

but it wasn’t really complete for my case. In the end it turned out I had to change the document as following.

Solution
If you want to convert a SSRS rdl from 2005 to 2000, you can try the following

1) Open the .RDL file in a text editor and change the XML.
2) Change the first node to look like this:

Report
xmlns=”http://schemas.microsoft.com/sqlserver/reporting/2003/10/reportdefinition”
xmlns:rd=”http://schemas.microsoft.com/SQLServer/reporting/reportdesigner”

3) Do a search for “Interactive” You should find 2 nodes InteractiveWidth and InteractiveHeight. You need to delete these nodes.

4) The XML in the RDL file is different between 2005 and 2000 when you want to pass parameters to a SQL procedure.

In 2000 they pass parameters this way in the RDL file. I used

&lt Query>
&lt CommandType> StoredProcedure< /CommandType>
&lt CommandText> =”procGetInvMovement”< /CommandText>
&lt QueryParameters>
&lt QueryParameter Name=”@BegDate”>
&lt Value> =Parameters!pBegDate.Value< /Value>
&lt /QueryParameter>
&lt QueryParameter Name=”@EndDate”>
&lt Value> =Parameters!pEndDate.Value< /Value>
&lt /QueryParameter>
&lt /QueryParameters>
&lt DataSourceName> JLG SQL< /DataSourceName>
&lt /Query>

and in 2005 they do it this way:

&lt Query>
&lt rd:UseGenericDesigner> true< /rd:UseGenericDesigner>
&lt CommandText> =”Execute procGetInvMovement ‘” & Parameters!pBegDate.Value & “‘, ‘” & Parameters!pEndDate.Value & “‘”< /CommandText>
&lt QueryParameters>
&lt QueryParameter Name=”pBegDate”>
&lt Value> =Parameters!pBegDate.Value< /Value>
&lt /QueryParameter>
&lt QueryParameter Name=”pEndDate”>
&lt Value> =Parameters!pEndDate.Value< /Value>
&lt /QueryParameter>
&lt /QueryParameters>
&lt DataSourceName> JLG SQL< /DataSourceName>
&lt /Query>

Notice how they don’t include the parameters in the commandtext tag in 2000

5) Delete the CommandType-tag if you want to use a query

6) In to the 2000 version of the .RDL file. You will need to add this line:
StoredProcedure after the first tag.

7) In the ReportParameters don’t use the tag Hidden

THIS IS NOT SUPPORTED SO I WOULD BACKUP YOUR REPORTS BEFORE ATTEMPTING THIS AND USE THIS ADVICE AT YOUR OWN RISK.


Tuesday 13 April 2010

Support SharePoint 2007 without SP2 ends on July 13th, 2010

Is your SharePoint 2007 farm already on Service Pack 2? If not, read this!

*** update April 12th, 2010 ***
Microsoft announced that the official retirement date for SP1 is 13th of July!
***

Source: http://blogs.technet.com/stefan_gossner/archive/2010/03/23/updated-retirement-date-for-wss-3-0-and-moss-2007-sp1.aspx

I've quoted the blog post of Stefan Goßner about the support of MOSS 2007
installation without SP2.

Please consider this information, if you're
not already planning to upgrade your systems!

"Based on the above listed information support for SharePoint
servers without SP2 will end on April 28th, 2010"
More
information:
http://blogs.technet.com/stefan_gossner/archive/2010/01/07/is-your-sharepoint-2007-farm-already-on-service-pack-2-if-not-read-this.aspx