Tuesday, December 21, 2010

SharePoint Reporting Options

If you need to display chart controls in SharePoint, there are number of options, including, but not limited to:
a) SSRS in Native or Integrated Mode
b) Excel Services
c) Performance Point Services
d) Custom or Third Party Silverlight Controls
e) “Fusion Charts” - based on Adobe Flash
f) JavaScript Control libraries
g) SharePoint 2010 Chart Web Part, which is simple to use, but powerful. I described the same in an older post of mine:
h) Access 2007/2010 Reports connecting to data in SharePoint List

i) Using ASP.Net Chart Controls. Here is a useful blog which describes the same:
http://rahul-vartak.blogspot.com/2010/08/using-aspnet-chart-control-in.html

j) SharePoint: Interactive Charts using Google Visualization API v2.0
Google provides a JavaScript based charting API. However, you need to get data from data source and feed it to Google. Alexander Bautz provides an wrapper JavaScript library, which provides configuration options, reads data from SharePoint Lists and generates the graphs and charts using Google API.
https://www.nothingbutsharepoint.com/sites/eusp/Pages/sharepoint-interactive-charts-using-google-visualization-api-v2-0.aspx
I have made my hands dirty with all the above.
So what is the best option or recommended option to use? IMHO, there is no single best option. Some options require server side configuration changes or deployment. Others can be used by uploading code/JavaScript files to a SharePoint document library or modifications through SharePoint Designer. Access Reports is a thick client option, and has its thick client pros-cons and can be used if you have few users.
The data can be fetched using CAML Queries in either C# or JavaScript, using Data View Web Parts with some level of gymnastics involving XSLT and JavaScript, or SharePoint List connectors.
Each option has its pros/cons and needs to be evaluated on case by case basis.
The list is by no means all exhaustive and all inclusive. I have listed only the most common I have come across. If you have an opinion or alternative option to recommend, feel free to share your thoughts in the comments below.

Monday, December 06, 2010

Opening Visual Studio 2005 Projects in Visual Studio 2010/2008

We recently had to modify legacy source code created in Visual Studio 2005. On opening the project file in VS 2010, it started the Conversion Wizard.


After clicking the usual Next, Next and Finish, it gave the message "Some errors occurred during Conversion. For more information, see the Conversion Report". The report gave 1 Error.

On trying to re-open the project file, it gave the message.

The project file 'D:\Test\MyProj.csproj' cannot be opened. The project type is not supported by this installation.

It was a SharePoint project, and it was looking for Visual Studio Extensions for SharePoint.

We had only Visual Studio 2010 on our machines and trying to install the Visual Studio extensions for VS 2010 will not help as we could not find the right 64 bit VS 2010 version.

I used an old trick learnt in my early programming days. Opening Visual Studio project file directly in notepad and modifying the same. The .csproj file is an XML file and we were interested in the ProjectTypeGuids which stores reference to the project type.

<ProjectTypeGuids>{9E5D3E2D-E4E2-418e-8D80-2F0DA9A94F9A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>


The GUID's stand for
{9E5D3E2D-E4E2-418e-8D80-2F0DA9A94F9A} = SharePoint Solution
{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} = Class Library

We removed the reference to SharePoint Solution GUID (and its semicolon separator), saved the file in notepad. And now when we open the project, the error is gone. Hurray!!!

Tuesday, November 30, 2010

Workflow .rules File blocked in SharePoint

We were recently working on a project which stored the Workflow Rules File (with .rules extension) in a SharePoint Document Library. The code programmatically extracted the .rules file from the SharePoint document library and used it further for business logic.


The approach makes the rules configurable, and described here.
http://msdn.microsoft.com/en-us/library/ff986245.aspx

While the code worked in our older MOSS 2007/Win 2003 world, it failed on SharePoint 2010-Win 2008 environment. The error was thrown while trying to access the file through code as well as SharePoint document library UI.

Issue 1: It initially gave a HTTP 404 Not Found Error while trying to access the .rules file

Resolution: .rules extension is blocked by IIS 7. You need to dig IIS log files to realize that its 404.7 error. To resolve, we need to enable .rules extension for our Web App. You can do the same by

a) Using IIS Management Console (inetmgr), Select Web Site, Click ‘Request Filtering’ and remove .rules extension

b) Modify Web.Config using Notepad or Visual Studio and configure fileExtensions node under requestFiltering.


Issue 2: Once the HTTP 404 error is resolved, it throws SharePoint error.

Resolution: In IIS, .rules extension is mapped to System.ServiceModel.Activation.HttpHandler and other handlers.

Using IIS Management Console, select Handler Mappings, and remove the mapping for .rules extension to System.ServiceModel.Activation.HttpHandler

I need to evaluate the impact of removing the handler. To be safe, I have renamed .rules to a dummy value .rules1 so it’s easier to revert. You can also modify web.config handlers node if you are comfortable with same.

Our code is now working after the above changes and  team able to proceed.

Friday, November 19, 2010

Add Custom Category to Search Refinement Panel

Goal: Display a custom Category(Facet) called Classification in the SharePoint 2010 Search Refinment Panel.



Initial Steps: Configure your custom column as Managed Property in Central Admin Search Settings. Only Managed Proprites can be displayed under Refinement Panel.

I will not discuss how to create Managed Property in this blog, but focus on Refinement Panel.

Next Steps: You need to edit the Web Part and configure its XML to display the custom Category.

MSND provides description of the XML syntax:
http://msdn.microsoft.com/en-us/library/ff625183.aspx

The above link is not sufficent and there are few additional things you need to know.

Use Default Configuration: The Web Part has a propety "Use Default Configuration" which you need to uncheck.

Unless you uncheck, you Custom XML wont be applied, and a lot of teams miss this setting.



Filter Category Definition: This is the XML input for the Refinement Panel Web Part. I create a XML file in Visual Studio and use the same for editing.

You need to add your custom Category. I added as following to the XML:

<Category Title="Classification" Description="Document Classification" Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator" MetadataThreshold="1" NumberOfFiltersToDisplay="4" MaxNumberOfFilters="20" SortBy="Frequency" SortByForMoreFilters="Name" SortDirection="Descending" SortDirectionForMoreFilters="Ascending" ShowMoreLink="True" MappedProperty="classification" MoreLinkText="show more" LessLinkText="show fewer" />

While most of the properties are self explantory and described in above MSDN article, I need to highlight a few.


MappedProperty: specifies Name of managed property. It is case sensitive and seemed to accept only lower case only. Though I called my managed property "Classification" with caps C, I had to set it to "classification" with lower c to make it work.

MetadataThreshhold: Specifies the minimum number of times the property should be present in Search Results to be considered important to be display.

I had very few docs in my dev environment, and my Custom Category will randomly show up. I have now set it to 1 and it displays as expected.

Enable Data View Caching: Performance Optimization option in web part, I had to uncheck it for my changes to be reflected. I have now checked it again and works fine.

Hope this helps others to save time in configuring the web part.

Tuesday, November 16, 2010

Search Results Customization RAW XML

You are trying to customizing the Search Core Results Web Part to display a custom column in Search Results. You have modifed the XSLT as expected, but dont get the desired column in the results. You need to verify that the column values are returned by Search Engine (Crawl + Index + Query) as expected. After all, Search Core Results Web Part is only applying XSLT transformation to the input (Search Results it recieves in XML format). If Column values are not returned by Search Engine, the Search Results Web part cant display the same in Search Results.

How do you verify the RAW XML. Well, you can apply the following XSLT to view the source XML (Dont forget to copy and backup the original XSLT to a notepad file, you will need the same to revert back).

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xmp><xsl:copy-of select="*"/></xmp>
</xsl:template>
</xsl:stylesheet>

If the required column is in RAW XML but not displayed in results, the problem is in your XSLT.
 
If the required column is missing in RAW XML, the problem is elsewhere. You need to validate if you have created Managed/MetaData Properties, Done a full or incremental crawl, modified the Search Core Results Web Part Fetched Properties and added the managed property to SelectedColumns.

Monday, September 06, 2010

SharePoint History - Product Names

Microsoft has change the product name for SharePoint multiple times, leading to some confusion in the industry and business.

Based on my understanding, putting a table for everyone’s reference. I will not delve into pre-2001 history.

VersionAssembly VersionLicensed Product – Better/Higher ProductBase Platform, Product with Limited Features, Free Version
2001xSharePoint Portal Server (SPS) 2001SharePoint Team Services (STS)
2003v11SharePoint Portal Sever (SPS) 2003, Microsoft Content Management Server (M CMS) 2002Windows SharePoint Services(WSS) 2.0
2007v12Microsoft Office SharePoint Server (MOSS) 2007Windows SharePoint Services(WSS) 3.0
2010v14SharePoint Server 2010SharePoint Foundation 2010
2013v15SharePoint Server 2013SharePoint Foundation 2013
2016v16SharePoint Server 2016NA**


* v13 skipped due to 13 being considered unlucky number by many customers.
** SharePoint Foundation is no longer available with SharePoint 2016

Portal from SPS 2003 was dropped as it lead people to believe that it can be used
only for Portal development and nothing else.

Office from MOSS 2007 was dropped as it lead some people to believe that it is an Office product like Word and Excel.

Hope Microsoft has got the name right this time with SharePoint Server 2010.
Update: No change in name with the release of SharePoint Server 2013 and 2016

The Microsoft cloud versions of SharePoint were called BPOS (Standard, Dedicated) in past.

Now they are referred as Office 365 SharePoint Online, or simply SharePoint Online. Unlike the On Premise version, SharePoint Online does not use a year in its name. SharePoint Online is an evergreen platform i..e. its updated frequently and users get to use the latest version of SharePoint

Still confused with version of SharePoint Online? Ok, let me take an example. Do you know which version of Facebook do you use? Or which version of Gmail do you use? You don't know, right. Same is true with SharePoint Online. Use SharePoint Online without worrying too much about the version.

There are some minor variations though, SharePoint Online Dedicated / Dedicated vNext and SharePoint Online Multi Tenant(MT). And you can turn on or off First Release features for our Office 365 tenant. First Release tenants and its users usually get the new features in beta or preview stage, before other production tenants.

Tuesday, January 19, 2010

Troubleshooting “An unexpected error has occurred” in SharePoint

Typical scenario in SharePoint Projects on hosted environment where Developers don’t have access to server:


Developer 1: SharePoint is throwing “An unexpected error has occurred” without giving any other information.

Developer 2: Did you try updating your Web.Config ? You need to set CallStack to false and customErrors mode to “Off”

Developer 1: Duh, I would have done that first thing if I had access to the server. I am working on a hosted SharePoint environment. I don’t have remote access to the machine, the event viewer and log files.

Developer 2: Then you are gone. Nothing can be done.

Developer 1: Oh God, Please Help Me!


You may face such scenarios in your project, don’t get tensed and give up. You need patience and common sense in such situations.

You can try to identify the root cause of the error in a methodical manner.

Step 1: Determine whether the error is at page level, page layout or master page.

Browse through different pages created using same layout. If the error is observed on Page A but not on Page B, the error is most likely on page A.

Browse through pages created using different layout. If error is observed on pages based on layout X, but not on pages based on layout Y, the error is most likely with the page layout X.

Temporarily change your Site or System master page. If changing the master page fixes the error, the error is most likely on the master page.

Step 2: Identify the control throwing the error.

Create a temporary copy of the page/ page layout / master page.

On the temporary copy, keep deleting chunks of code (table, div tag, control, webpart) and refresh the page in the browser till your page starts working. If your page stopped throwing error after removing control X, the error is likely to be in control X.

You can also do the reverse by starting with a blank page layout or master page, and adding controls one at a time till your page breaks.

Step 3: Fix the broken or corrupted control.

Once the control throwing error has been identified, your job is easier. Look for invalid attributes, properties, missing tags, dependencies, compare with implementation in default or other custom pages.

This simple approach has helped us troubleshoot issues on multiple occasions.

Developer 1: I found the issue, and fixed it.
Developer 2: Wow! You are the real SharePoint Guru.
Client: Great work. You are rock stars!

Note: Do not forget to hide your temporary pages from navigation while you are troubleshooting. And do not forget to delete them once you are done.

Monday, January 04, 2010

Installing SharePoint 2010 on Win 7 64 bit OS

With the intention of installing SharePoint 2010 on my box, I switched my OS to 64 bit version of Win 7.

To install SharePoint 2010, I followed the steps mentioned in MSDN article http://msdn.microsoft.com/en-us/library/ee554869(office.14).aspx . There were few hiccups that I had while running  the SharePoint configuration wizard, and have described the solutions below for the benefit of all.
--------------------------------------------------------------------------------------------------
1) Error: Failed to create the configuration database.

An exception of type Microsoft.SharePoint.SPException was thrown. Additional exception information: User cannot be found.

Microsoft.SharePoint.SPException: User cannot be found.

at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, SPSiteSubscription siteSubscription, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)

at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPSiteSubscription siteSubscription, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, Boolean useHostHeaderAsSiteName)

at Microsoft.SharePoint.Administration.SPAdministrationWebApplication.CreateDefaultInstance(SqlConnectionStringBuilder administrationContentDatabase, SPWebService adminService, IdentityType identityType, String farmUser, SecureString farmPassword)

at Microsoft.SharePoint.Administration.SPFarm.CreateAdministrationWebService(SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)

at Microsoft.SharePoint.Administration.SPFarm.CreateBasicServices(SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)

at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword, SecureString masterPassphrase)

at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
--------------------------------------------------------------------------------------------------

Solution: You need to be connected to the network/domain while running the SharePoint configuration wizard.
--------------------------------------------------------------------------------------------------
 
2) Error: Failed to create the configuration database.


An exception of type System.Security.Cryptography.CryptographicException was thrown. Additional exception information: The data is invalid.



System.Security.Cryptography.CryptographicException: The data is invalid.

at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)

at Microsoft.SharePoint.Administration.SPCredentialManager.get_MasterKey()
at Microsoft.SharePoint.Administration.SPCredentialManager.GetFarmEncryptionKey()
at Microsoft.SharePoint.Administration.SPCredentialManager.EncryptWithMasterKey(SecureString sstrPassphrase)
at Microsoft.SharePoint.Administration.SPEncryptedString.SetSecureStringValue(SecureString sstrValue)
at Microsoft.SharePoint.Administration.SPCertificateAuthority.Provision()
at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword, SecureString masterPassphrase)
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
--------------------------------------------------------------------------------------------------
Solution: Delete Registry Key (i was skeptical to directly edit the registry, but it worked for me)


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Secure\FarmAdmin
--------------------------------------------------------------------------------------------------


3) Failed to create sample data.


An exception of type Microsoft.Office.Server.UserProfiles.UserProfileException was thrown. Additional exception information: Unrecognized attribute 'allowInsecureTransport'. Note that attribute names are case-sensitive. (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebClients\Profile\client.config line 56)

Microsoft.Office.Server.UserProfiles.UserProfileException: Unrecognized attribute 'allowInsecureTransport'. Note that attribute names are case-sensitive. (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebClients\Profile\client.config line 56) ---> System.Configuration.ConfigurationErrorsException: Unrecognized attribute 'allowInsecureTransport'. Note that attribute names are case-sensitive. (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebClients\Profile\client.config line 56)

at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)

at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)

at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)

at System.Configuration.ConfigurationSectionCollection.Get(String name)
at System.ServiceModel.Configuration.ServiceModelSectionGroup.get_Client()
at Microsoft.Office.Server.UserProfiles.MossClientBase`1.GetServiceBinding(String endpointConfigurationName)
at Microsoft.Office.Server.UserProfiles.MossClientBase`1.GetChannelFactory(String endpointConfigurationName)
at Microsoft.Office.Server.UserProfiles.MossClientBase`1.get_Channel()
at Microsoft.Office.Server.UserProfiles.MossClientBase`1.ExecuteOnChannel(String operationName, CodeBlock codeBlock)
at Microsoft.Office.Server.UserProfiles.ProfilePropertyServiceClient.ExecuteOnChannel(String operationName, CodeBlock codeBlock)

--- End of inner exception stack trace ---

at Microsoft.Office.Server.UserProfiles.ProfilePropertyServiceClient.ExecuteOnChannel(String operationName, CodeBlock codeBlock)
at Microsoft.Office.Server.UserProfiles.ProfilePropertyServiceClient.GetProfileProperties()
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.RefreshProperties(Guid applicationID)
at Microsoft.Office.Server.Utilities.SPAsyncCache`2.GetValueNow(K key)
at Microsoft.Office.Server.Utilities.SPAsyncCache`2.GetValue(K key, Boolean asynchronous)
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.InitializePropertyCache()
at Microsoft.Office.Server.Administration.UserProfileApplicationProxy.Provision()
at Microsoft.SharePoint.PostSetupConfiguration.EvalModeProvisionTask.ProvisionServiceApplicationsAndProxies()
at Microsoft.SharePoint.PostSetupConfiguration.EvalModeProvisionTask.Run()
at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()

--------------------------------------------------------------------------------------------------

Solution: You need to install hotfix KB976462 (FIX FOR: WCF: Sharepoint Shared Services Roll-up).
You need to restart your machine after installing the hot fix.
--------------------------------------------------------------------------------------------------

Updates: Upating the article almost after 2.5 years since I originally posted it
4)
Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at Microsoft.SharePoint.Administration.SPFarm.CurrentUserIsAdministrator(Boolean allowContentApplicationAccess)
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Microsoft.SharePoint.Administration.ISPPersistedStoreProvider.DoesCurrentUserHaveWritePermission(SPPersistedObject persistedObject)
   at Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate()
   at Microsoft.SharePoint.Administration.SPFarm.Update()
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.RegisterDefaultDatabaseServices(SqlConnectionStringBuilder connectionString)
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Provision(SqlConnectionStringBuilder connectionString)
   at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword, SecureString masterPassphrase)
   at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
   at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
   at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
--------------------------------------------------------------------------------------------------
Solution: You need to install Windows6.1-KB974405-x64 (Windows Identity Foundation)
--------------------------------------------------------------------------------------------------

Sunday, January 03, 2010

SharePoint 2010 Developer Platform

SharePoint v/s ASP.Net: When does it make sense to build an application on SharePoint instead of on raw ASP.NET? What are the application types for which SharePoint is best suited? And what applications types are SharePoint misfits and should be built using ASP.Net or other technologies?



The “SharePoint 2010: Developer Platform” White Paper tries to answer the above questions.
http://www.microsoft.com/downloads/details.aspx?FamilyID=5184cb27-98d9-4cc0-bb0b-4b24d5b62db6&displaylang=en

Recommended reading material.