Thursday, November 6, 2008

Installing SQL Reporting Services and MOSS 2007 on the Same port ( default : 80)

If you have both MOSS 2007 ( Microsoft Office SharePoint Server) and Reporting Services ( not in SharePoint integrated mode) installed on the same IIS virtual server, then you have to make the below updates in web.config for them to work:
  1. In the Root web.config to comment out the below. Otherwise the reportserver will give sessionState partitionResolver Issue
    <!-- <sessionstate mode="SQLServer" timeout="60" allowcustomsqldatabase="true" partitionresolvertype="Microsoft.Office.Server.Administration.SqlSessionStateResolver, Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />-->
  2. In both Reportserver and ReportManager vdir web.config, the following should be added under appSettings. Otherwise you will get ReportViewer error messages
    <remove key="ReportViewerMessages">
    or
    you disable inheritance from Root Web.Config. You can use inheritInChildApplications attribute in a configuration file to specify that the settings defined in the
    location element for the root of a Web site should not be inherited by child applications:

    This is because , by default MOSS uses /reports url for it’s report center and it’s the same virtual dir url for native SQL Reporting Services report manager as well.

Tuesday, November 4, 2008

How to deploy a custom field with custom properties from a feature

When MOSS 2007 was still in beta and features and custom fields were new areas to discover we created the classic regular expression field type too, just to play with and learn the new technology.
Our implementation SPFieldRegEx was inherited from the Text type and had three custom properties defined in the field type definition XML:


<PropertySchema>
<Fields>
<Field Name="RegEx" DisplayName="Regular Expression" MaxLength="255" DisplaySize="15" Type="Text">
</Field>
<Field Name="MaxLen" DisplayName="Maximum length" MaxLength="3" DisplaySize="3" Type="Integer">
<Default>255</Default>
</Field>
<Field Name="ErrMsg" DisplayName="Validation message" MaxLength="255" DisplaySize="30" Type="Text">
<Default>The value does not match the regular expression</Default>
</Field>
</Fields>
</PropertySchema>

The RegEx property stores the regular expression pattern, the MaxLen controls the maximal length of the field content and finally, the ErrMsg holds the validation message to be displayed when the input text does not match with the regular expression.

There is nothing interesting in that up to this point, but if you would like to deploy this custom field using a feature setting custom values to the properties you might encounter some difficulty.

Since I haven’t found that documented neither in the WSS SDK nor on developer blogs in the past years, I decided to share my experience.If you create your feature definition for the field as you do normally with the built in field types, the result is the following XML:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{54634385-A8AC-4898-BF24-E533EB23444F}" Name="RegExField" DisplayName="RegExField" StaticName="RegExField" Group="Grepton Fields" Type="SPFieldRegEx" Sealed="FALSE" AllowDeletion="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3/fields" Description="This is the RegEx field" RegEx="[0-9]" MaxLen="20" ErrMsg="Error!"/>
</Elements>

But if you try to install the feature, you get the following error:

Feature definition with Id 6fd6ca04-3ac3-490f-b22f-4461a2253001 failed validation, file 'feature_definition2.xml', line 5, character 299:
The 'RegEx' attribute is not allowed.

If you remove the RegEx attribute, the same error message appears with MaxLen, if you remove that too, the ErrMsg causes problem.

So what to do to make this attributes allowed?The schema of the features is defined in the wss.xsd. Now the most important part for us is the FieldDefinition complexType that is responsible – what a surprise! – for describing the format of the field definitions in the features. Besides other things it contains the list of the allowed attributes.

<xs:complexType name="FieldDefinition" mixed="true">
...
<xs:attribute name="Decimals" type="xs:int" />
<xs:attribute name="Description" type="xs:string" />
...
<xs:attribute name="DisplayName" type="xs:string" />
...
<xs:attribute name="FillInChoice" type="TRUEFALSE" />
...
<xs:attribute name="Hidden" type="TRUEFALSE" />
...
<xs:attribute name="Max" type="xs:float" />
<xs:attribute name="Min" type="xs:string" />
...
<xs:attribute name="Name" type="xs:string" use="required"/>
...
<xs:attribute name="ReadOnly" type="TRUEFALSE" />
...
<xs:attribute name="Required" type="TRUEFALSE" />
...
<xs:attribute name="Title" type="xs:string" />
<xs:attribute name="Type" type="xs:string" use="required" />
...
<xs:attribute name="ID" type="UniqueIdentifier" />
<xs:attribute name="Group" type="xs:string" />
<xs:attribute name="MaxLength" type="xs:int" />
<xs:attribute name="SourceID" type="xs:string" />
<xs:attribute name="StaticName" type="xs:string" />
...
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>

The fragment above contains only the most widely used attributes for example.

One quick and dirty solution would be to include our custom attributes in the XSD schema but this probably wouldn’t be a supported method. Fortunately in this case MS has left the back door open: if you check the last attribute in the schema, it is anyAttribute with namespace ##other, meaning that you can inject your own attributes in the XML files using your own namespace.

After a minor modification in the feature definition XML (highlighted below) the XML was passed the schema check and our custom field feature was installed successfully.


<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
<Field ID="{54634385-A8AC-4898-BF24-E533EB23444F}" Name="RegExField" DisplayName="RegExField" StaticName="RegExField" Group="Grepton Fields" Type="SPFieldRegEx" Sealed="FALSE" AllowDeletion="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3/fields" Description="This is the RegEx field" xmlns:RegEx="[0-9]" xmlns:MaxLen="20" xmlns:ErrMsg="Error!"/>
</Elements>

But I faced another problem. Although this XML passed schema Validation, It didn't update extended attributes. After investigations I found only way to do that create event receiver for activation.

public class LookupFeatureEvents : SPFeatureReceiver
{
private const string CONST_FIELD = "Field";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string str = string.Empty;
string lastXml = string.Empty;
SPElementDefinitionCollection elementDefinitionCollection = properties.Definition.GetElementDefinitions(new CultureInfo(1033));
foreach (SPElementDefinition elementDefinition in elementDefinitionCollection)
{
if (elementDefinition.ElementType == CONST_FIELD)
{
XmlNode node = elementDefinition.XmlDefinition;
List<string> arrNS = new List<string>();
for(int i=0; i<node.Attributes.Count; i++)
{
if (node.Attributes[i].Prefix!=string.Empty)
arrNS.Add(node.Attributes[i].Prefix);
}
SPSite parent = properties.Feature.Parent as SPSite;
if (parent != null)
{
SPWeb web = parent.RootWeb;
string webid = web.ID.ToString("D");
string fieldId = node.Attributes["ID"].Value;
SPField lookup = web.Fields[new Guid(fieldId)];
lastXml = node.OuterXml;
for (int i = 0; i < arrNS.Count; i++)
{
lastXml = lastXml.Replace(arrNS[i] + ":", "");
}
lastXml = lastXml.Replace("xmlns=\"http://schemas.microsoft.com/sharepoint//"","");
lookup.SchemaXml = lastXml; lookup.Update(true);
}
}
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//throw new NotImplementedException();
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
//throw new NotImplementedException();
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
//throw new NotImplementedException();
}
}

Monday, November 3, 2008

An unhandled exception occurred in the user interface.Exception Information: OSearch (Administrator)

I was getting this error while trying to start the Office SharePoint Server Search service on a standalone dev machine that I was configuring. The machine was not a part of any domain so I would just enter the username for the search account without the domain name. To solve this error one needs to provide the MachineName\AccountName instead of AccountName for the search account to use

Friday, October 31, 2008

Browser Compatibilty forOffice SharePoint Server

The newer version of sharepoint , MOSS 2007 has better cross browser compatibility than the older version .It supports the following browswer :

Windows
Firefox 1.5+
Netscape 8.1+
Mozilla 1.7+

Macintosh
Safari 2.0+
Firefox 1.5+

Unix/Linux
Firefox 1.5+
Netscape 7.2+

Check out the following article to completely understand the browser compatibility:
http://technet.microsoft.com/en-us/library/cc263526.aspx

Tuesday, October 28, 2008

Restrict Anonymous Users to view Form Pages in MOSS 2007

If you enable the anonmous access in MOSS 2007 Site. The anonmous user will able to access the form pages like:
http://server/pages/forms/allitems.aspx

If you want to restrict anonymous users to access those default form pages.

Enable the ViewFormsPagesLockdown Feature to restrict anonymous users to access the site

Syntax:
stsadm.exe -o activatefeature -url -filename

Example:
stsadm.exe -o activatefeature -url http://server -filename ViewFormPagesLockdown\feature.xml

How to change your personal information in MOSS 2007

Remember how you had to scan through user information pages to get the correct display name. In MOSS 2007 this is more convenient. By default SharePoint will display 'domain\username' in the fields related to who was last participating in a document, list, survey, etc...

To change from 'domain\username' to show your actual name follow the instructions below:
  1. Log into the Portal
  2. Click the Welcome domain\username in the upper right hand corner
  3. A drop down menu will appear
  4. Click My Settings
  5. Click Edit Item
  6. Change your Name field and fill in any additional fields as necessary
  7. Click OK

To verify your name has changed look at the Welcome message. It should say 'Welcome Your Name' instead of your domain\username.

This tip is not for Moss 2007 but for WSS v3 ! It won't work with Moss !With Moss, you have 2 ways to modify profile information:

  1. on the ssp edit profile page (ony for admins)
  2. on my site, edit my profile

Limiting the SharePoint People Picker

In SharePoint there will be times where you will want to control what results the people picker returns. The most common scenarios are in an extranet or hosting environment.
There are four strategies which can be used to limit the people picker. All of these are managed using STSADM commands. The four strategies are:-
  1. Applying a custom active directory filter
  2. Limiting the people picker search to within a site collection
  3. Limiting the people picker search to within an Active Directory(AD) Organisational Unit(OU)
  4. Disable returning windows accounts when the authentication method for the web application is via forms based authentication

    Some of these commands are not very well known and some are new in MOSS SP1.

Custom Active Directory Filter

To limit the search to a custom AD filter use the STSADM property peoplepicker-searchadcustomfilter

This property is new in SP1 and when a people search is executed it will return results that only match the combination of the built in query and the custom filter that is defined for the site collection.

To create a custom filter which will only return users with a title of Vice President run the following command for their site collection.

stsadm -o setproperty -url http://server/sites/vp-site -pn peoplepicker-searchadcustomfilter -pv ((Title=Vice President))

There is also a similar property with slightly different functionality called peoplepicker-searchadcustomquery. This command is also available pre-SP1 however you should ensure that the Active Directory attribute that is being queried is indexed; otherwise there may be performance problems.

Search only within a site collection

This option is suitable to a classic extranet environment where the internal and external user accounts are in the active directory however you do not want the extranet users to be able to search and browse the directory listing. Note that this is not 100% secure, users can still search Active Directory using a fully qualified logon name, regardless of this property setting. To only list users who have been added to a site collection use the property - peoplepicker-onlysearchwithinsitecollection. As an example:

stsadm -o setproperty –url http://extranet.company.com/sites/project1 –pn peoplepicker-onlysearchwithinsitecollection –pv yes

Consider for this site collection there is an AD user account: 'Gavin Adams COMPANY\gadams)' who is not a member of the site collection and the user 'John Doe (COMPANY\jdoe)' is already a member of the site collection. The behaviour that the users will see when they add a user to the site is as follows.

Search only within an AD OU

To limit the search to a path with AD (ie an OU) use the operation setsiteuseraccountdirectorypath

This operation is new in SP1. Once this is set for a site collection no other users can be added to the site collection that are not within that OU. Note that only one OU path can be specified per site collection. An example of this command is:-

stsadm -o setsiteuseraccountdirectorypath -path "OU=Employees,DC=Company,DC=com" –url http://server/sites/teamsite

Often administrative user accounts are in a different OU from the users for a site collection, therefore after the above operation has been applied to a site collection, the property peoplepicker-serviceaccountdirectorypaths is used to define the location of the administrator accounts. For example:-

stsadm -o setproperty -url http://server/sites/teamsite -pn peoplepicker-serviceaccountdirectorypaths -pv " OU=MOSS-Gods,DC=Company,DC=com

Non Windows Accounts only via FBA

If you have a web application that is configured to use forms based authentication and the account and membership provider is not Active Directory (eg a SQL database), then the property peoplepicker-nowindowsaccountsfornonwindowsauthenticationmode can be set against the web application or zone so that the people search will not return any active directory user accounts.

An example of the command with a web application https://extranet.company.com would be:

stsadm -o setproperty -url https://extranet.company.com -pn peoplepicker-nowindowsaccountsfornonwindowsauthenticationmode -pv yes

Note:
To use peoplepicker-searchadforests with credentials, which you need to specify if you don’t have two-way trusts in place, you must first set an encryption key:
stsadm.exe -o setapppassword -password key
This sets a key that will be used to encrypt/decrypt the password in the content database. Failure to do this results in a “command line error” message.
Secondly, the peoplepicker runs under the credentials of the application pool the site is running in(password of this credential user). Make sure the application pool identity is a domain account with the right permissions.