May 17, 2013

Performance problem: SharePoint site is very slow


Performance Problem:
SharePoint 2010 Server site and Central Admin are unrealistically too slow (16 seconds or more) to open in browser, without showing any error. You added much more server hardware resources (CPU, RAM and HDD) but this solution fails to improve performance.


Analysis:
In IE, hit F12 key and found that the site home page took 73 seconds to load!


In Central Admin, click on the Health Analyzer to find an interesting item in the performance section: “Application pools recycle when memory limits are exceeded.”





According to this Microsoft article here:
Application pools recycle because memory limits have been enabled and exceeded. Recycling based on memory limits is not usually necessary in a 64-bit environment, and therefore recycling should not be enabled. Unnecessary recycling can result in dropped requests from the recycled worker process and slow performance for end users who are making requests to the new worker process.

In faulty server -> IIS Manager -> Application Pools -> select the ‘SharePoint – 80' -> right-click -> click Recycling. We see the following 2 values:
·         Virtual memory usage (in KB): is checked to use 1024 KB
·         Private memory usage (in KB): is checked to use 1024 KB


Cause:
Apparently the application pool (SharePoint – 80) is recycling each time it reaches the memory limit as set above to 1024 KB. This happens many times during page loading so the total time needed to load the page is too long.


Solution:
Follow this procedure:
1.   Current user account must be a member of the Farm Administrators group.
2.   Identify the failing server(s) and repeat the following steps on each failing server
[Central Administration -> Monitoring -> click Review problems and solutions, and then find the name of the server in the Failing Servers column, example: SharePoint - 80].
3.   Current user account must be a member of the Local Administrators group on each server in step 2 above.
4.   In faulty server -> IIS Manager -> Application Pools -> select the ‘SharePoint – 80' -> right-click -> click Recycling. Clear the 2 check boxes of Virtual memory usage (in KB) and Private memory usage (in KB) -> click Next -> click Finish. (Repeat this step for all AppPools of slow WebApps).




Open the site again, and now it’s really fast!


May 8, 2013

Site creation error: the folder does not exist



I have a SharePoint 2010 team site which has a doc lib called "Process Deliverables" and it contains folders with numbered names:


'0.SOW – Charter'
'1.Review Decision Report'
'2.Final Deliverables'

I saved this site into a template with its content successfully. When trying to create a site based on the template, it throws an error:
"Adding properties to the folder with url {..} failed while activating feature, the folder does not exist."

The url here is: ‘Process Deliverables/0.SOW – Charter’


Analysis:
I renamed the first folder '0.SOW – Charter' into '0_SOW – Charter' (without quotes). Then saved the site as a template and tried to create a site based on it. It threw a different error with similar message:


Here the url is: 'Process Deliverables/1.Review Decision Report'. This means the first folder passed successfully but the next folder item in the library fails.


Cause & Solution:
Special characters such as " # % & * : < > ? \ / { | } ~ . generally cannot be used in folder names. 
A complete list of these characters here.
In our case: the dot (.) is allowed but must be not consecutively used neither at the start nor the end of name. However, for some reason it is appearing to be causing the error here. Rename your folder if they have any of the above including the dot, example:

'0_SOW – Charter'
'1-Review Decision Report'
'2) Final Deliverables'


Now save your site as a template and create sites happily!







May 4, 2013

Custom values on Choice column - Part 2


In Part 1 here of this article, we understood how the default choices work in OTB Create Column page (FldNew.aspx) in SharePoint 2010.
Now, its time to start the fun. Let's see examples of how we can show custom choice values:

First, remember to always make a backup copy of any OTB file before customizing it.

Example 1: Change static text values in resource file
Open the wss.en-US.resx (located in C:\inetpub\wwwroot\wss\VirtualDirectories\80\App_GlobalResources directory) using notepad or Visual Studio. Search for the keys, and replace the default values with your custom values such as (X, Y, and Z).


And this is how it will look like when creating new column:


There are only 3 keys to be used here. The downside of changing values for these 3 keys is that this will impact other pages, for example these keys are used in qstedit.aspx page used in survey lists. 
You can create new keys with custom values inside wss.en-US.resx and reference them through a a GetGlobalResourceObject()  in FldNew.aspx page.


Example 2: Custom static choices on page:
You can define your static strings directly without the need to resources file.
Edit FldNew.aspx, and replace the whole original inline code (highlighted yellow portion in Part 1) with this:

SPHttpUtility.HtmlEncode(
            "January" + "\r\n" + "Febraury" + "\r\n" + "March"+ "\r\n" +
            "April" + "\r\n" + "May" + "\r\n" + "June" + "\r\n" +
            "July" + "\r\n" + "August" + "\r\n" + "September" + "\r\n" +
            "October" + "\r\n" + "November" + "\r\n" + "December"
            ,Response.Output);


And this is how it will look like:



Example 3: Custom dynamic strings:
We can provide list of numbers from 0 to 9. Put the following code instead of the inline code (highlighted yellow portion in Part 1) in page. Set the rows parameter inside the textarea tag to expand the choices box to show more values as required.

        string ChoicesTxt = "0";
       
        for (int i=1; i<10; i++)
            ChoicesTxt += "\r\n" + i.ToString();
       
       // write the choices string into idChoices control on page
       SPHttpUtility.HtmlEncode(ChoicesTxt,Response.Output);

 And it will like this:


Example 4: Custom data from SharePoint list:
Create a custom list named "MyChoices" and add your choice values in Title field. Adjust the permissions to make it readable by all farm users or elevate the privileges through code. Replace the idChoices inline code (highlighted yellow portion) with the following:


        string ChoicesTxt = "";
        bool  _CustomChoicesError = false;
       
        try
        {
            SPWeb web = SPContext.Current.Web;
            SPList MyChoicesList = web.Lists.TryGetList("MyChoices");
            if (MyChoicesList != null)
            {
                // if lists exists, read all the items
                SPListItemCollection MyChoices = MyChoicesList.Items;
                foreach (SPListItem choice in MyChoices)
                {
                    ChoicesTxt += choice.Title + "\r\n";  
                }
            }
            else
                _CustomChoicesError = true; // list does not exist
        }
        catch (Exception ex)
        {
            _CustomChoicesError = true;
        }
       
        // in case of error, revert back to original choices
        if (_CustomChoicesError)
            ChoicesTxt = "Enter Choice #1\r\nEnter Choice #2\r\nEnter Choice #3\r\n";
       
        // write the choices string into idChoices control on page
        SPHttpUtility.HtmlEncode(ChoicesTxt,Response.Output);

The list (left), and how the values will look like (right):



If the 'MyChoices' list is deleted or an error occurred during data retrieval, then the page will display the original values.
Note: When you create a column using custom choice values, change value of any of the items temporarily and then undo the change. This is to trigger clearOutDefaultWithCheck() for the default value control to show the first value (its default behavior is to take its value from the resources files). Also you can do this by adding more code to handle this.


I hope you enjoyed with these ideas about customizing the choice values across your farm.