Wednesday, August 24, 2011

SiteMap Providers static property issue


There is a time when we need to modify a sitemap provider object and then use it.

Scenario:
We need to build a sub navigation control but we don’t want to include pages

Example code:
PortalSiteMapProvider sitemapprovider =                    (PortalSiteMapProvider)SiteMap.Providers["CurrentNavSiteMapProvider"];
               
sitemapprovider.IncludePages = PortalSiteMapProvider.IncludeOption.Never;

The problem with the code above is:
1.       The SiteMap.Providers property is a static property. It returns the object reference to the single instance of the provider.
2.       Modifying the object permanently changes the value.

One way to avoid this issue is to save the value of the property temporarily and then rollback the value back.

Example code:
ortalSiteMapProvider sitemapprovider =
(PortalSiteMapProvider)SiteMap.Providers["CurrentNavSiteMapProvider"];
               
var tempIncludePages = sitemapprovider.IncludePages;

sitemapprovider.IncludePages = PortalSiteMapProvider.IncludeOption.Never;

sitemapprovider.IncludePages = tempIncludePages;

This simple workaround seems to work properly.

Hope this helps J

Wednesday, June 15, 2011

SharePoint 2010 Broken Page Menu Ribbon (Keep on Loading)

My ribbon page menu suddenly stopped working this afternoon. Clicking the page menu gave me the loading icon without any progress.



After some investigation I found out that the code which I added this morning is the problem.

        String.prototype.startsWith = function(str){
            return (this.toLowerCase().indexOf(str) == 0);
        }

Apparently “startsWith” is a reserved word so changing the function name into another name fixed the problem.

A friend of mine told me “SharePoint keeps you young by forcing you to learn new stuffs almost everyday”.
And he is right J


Monday, May 30, 2011

SharePoint 2010 Fields or Columns Naming Problem

I was hammered by a bug found by our client. They were trying to reorder fields of a custom list and for some reason SharePoint threw the following error.


After hours and hours of investigation I finally found out what the problem is.
There were spaces in the name property of the fields. In theory SharePoint should have converted the spaces into “_x0020_” and everything should be okay. However reordering fields of this custom list produces the error above.

SharePoint does not like:
  <Field ID="{176C37CB-99E2-4730-8B61-C994151094B8}" Name="Field 1 With Spaces" StaticName="Field1WithSpaces" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="FESA.SPS2010.Internet" DisplayName="Field 1 With Spaces" Type="Note" NumLines="10" RichText="TRUE" Description="Field 1 With Spaces" RichTextMode="FullHtml"></Field>
  <Field ID="{DC7451BC-BF4C-43F1-B443-E297190C008A}" Name="Field 2 With Spaces" StaticName="Field2WithSpaces" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="FESA.SPS2010.Internet" DisplayName="Field 2 With Spaces" Type="Note" NumLines="10" Description="Field 2 With Spaces" RichText="TRUE" RichTextMode="FullHtml" />

But it likes:
  <Field ID="{176C37CB-99E2-4730-8B61-C994151094B8}" Name="Field1WithoutSpaces" StaticName="Field1WithoutSpaces" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="FESA.SPS2010.Internet" DisplayName="Field 1 Without Spaces" Type="Note" NumLines="10" RichText="TRUE" Description="Field 1 Without Spaces" RichTextMode="FullHtml"></Field>
  <Field ID="{DC7451BC-BF4C-43F1-B443-E297190C008A}" Name="Field2WithoutSpaces" StaticName="Field2WithoutSpaces" SourceID="http://schemas.microsoft.com/sharepoint/v3" Group="FESA.SPS2010.Internet" DisplayName="Field 2 Without Spaces" Type="Note" NumLines="10" Description="Field 2 Without Spaces" RichText="TRUE" RichTextMode="FullHtml" />

So the lesson is not to have any spaces (or any invalid characters) in the name of the Fields.

Have a great day everyone.

Wednesday, April 20, 2011

Robots.txt prevents SharePoint 2010 search crawler from crawling sites

As per our operation manager’s request I added robots.txt on our preview server to prevent Google’s bot or Bing’s bot from indexing our client’s preview sites.

Original robots.txt:
User-agent: *
Disallow: /

Effectively it should stop all legitimate bots from indexing preview sites. However this also stopped SharePoint 2010’s search crawler from crawling the sites. Any full crawl gave me 0 results.

The solution is to allow SharePoint 2010’s search crawler but to disallow other bots.  Now how do we find the user agent string for SharePoint 2010’s crawler?
If you go to Registry Editor and open the following:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager\UserAgent
You will find the UserAgent string used by SharePoint 2010’s crawler.
So all I had to do was edit my robots.txt to allow that particular user agent to index our SharePoint 2010 sites.

Updated robots.txt:
User-agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows NT; MS Search 6.0 Robot)
Allow: /
User-agent: *
Disallow: /

Hope this helps :)

Tuesday, April 19, 2011

Updating external content type for SharePoint 2010 Business Connectivity Service

Our client submitted a request to update their existing External Content Type used for BCS. The request was so simple: rename Address field into Department and add 1 extra field. I thought this should be easy.

So I updated the employee model and redeployed the solution. But for some reason the changes didn’t get reflected in the content type. I have tried everything from resetting IIS, clean solution, rebuild solution, even copy and paste the dll directly to the GAC without any result.

After further investigation I found out that the type descriptor (which you can see from BDC explorer or by opening the bdcm file in notepad) are not automatically updated.
So that is the lesson, the type descriptors needs to be updated manually.


Wednesday, March 30, 2011

Printing in SharePoint 2010 without header, navigation and some other elements

I am pretty sure most of you know about this but perhaps just never thought about it.

Being able to print is one of the most essential requirements of a website. Eventually user want to be able to print the content of a page but perhaps without the header, navigation or some other SharePoint’s element.

This is one simple trick that does the job for me on hiding those elements.

/* Print styles */
@media print
{
    .contentSkip, .s4-notdlg,
    #stuffNotToBePrinted, #s4-ribbonrow, .header, #header
    {
        display: none !important;
    }
}

Just add the above styling to your style sheet (obviously you need to add the things you want to hide to the above css style) and those elements should be hidden.

Have a nice day J

Tuesday, February 15, 2011

Disposing SPSite and SPWeb

Most of the time when we are working with a site or a web we would put a using statement such as these:
using (SPSite siteCollection = new SPSite("http://evan.local"))
{
    // Code here
}
using (web = site.OpenWeb("search"))
{
    // Code here
}
The reason is so that site collection / the web are disposed properly.

However trying to do similar thing in:
using (SPSite site = SPContext.Current.Site)
{
       Code here
}
using (SPWeb web = site.RootWeb)
{
       Code here
}

Will give you the following error in the log:

Unexpected    Detected use of SPRequest for previously closed SPWeb object.  Please close SPWeb objects when you are done with all objects obtained from them, but not before.


The reason is the SPContext (together with the site collection/web property in the object) will be automatically disposed when SharePoint finish with it. By putting them into the “using” statement, we are actually disposing the object when they are still being used.

So the conclusion:
If you are opening a site / a web then use “using” statement;
If you are utilising a site/web object from a property of the SPContext object then please do not use “using” statement.

Have a great day everyone J

Wednesday, February 2, 2011

Using a 3rd party control in SharePoint 2010

In this example I was trying to use Recaptcha in one of my custom SharePoint Page.

In normal ASP .Net registering the following TagPrefix should be enough:
<%@ Register TagPrefix="recaptcha" Namespace="Recaptcha" Assembly="Recaptcha" %>

Then I should be able to use the control just like this:
<recaptcha:RecaptchaControl ID="recaptcha" runat="server" PublicKey="SOME_PUBLIC_KEY" PrivateKey="SOME_PRIVATE_KEY" />

However SharePoint did not like it, instead I was getting the following error:
System.IO.FileNotFoundException: Could not load file or assembly 'Recaptcha' or one of its dependencies. The system cannot find the file specified.    at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)     at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)     at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)     at System.Reflection.Assembly.Load(String assemblyString)     at System.Web.Configuration.CompilationSection.LoadAssembly(String asse...      a475e341-2fe9-435c-916f-189bee006e81

The solution is to register recaptcha using the fully qualified name including the PublicKeyToken like this:
<%@ Register TagPrefix="recaptcha" Namespace="Recaptcha" Assembly="Recaptcha, Version=1.0.5.0, Culture=Neutral, PublicKeyToken=9afc4d65b28c38c2" %>

Hope this helps.

Wednesday, January 19, 2011

Sitefinity 3.7 newsletter module error

This morning one of our clients reported that clicking on the Newsletter module tab in the Sitefinity’s administration produces an error.

The reason is Sitefinity automatically generates service assembly in /Sitefinity/ServiceAssemblies/3889AC4AF542BAC3C62ABB154E78FEA8.dll

This dll depends on the host machine and Sitefinity’s version among other things.
So if you copy the site from other place then most likely you will get the error when trying to access the newsletter module.

If you search Sitefinity’s forum you will find that deleting the dll should force Sitefinity to regenerate the dll. However sometimes you still get the error even after deleting the dll.
One thing that I found useful is dropping the newly regenerated dll into the bin folder. It always fixes the problem for me.